Coverage Report

Created: 2025-08-26 06:20

/src/frr/bgpd/bgpd.c
Line
Count
Source (jump to first uncovered line)
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/* BGP-4, BGP-4+ daemon program
3
 * Copyright (C) 1996, 97, 98, 99, 2000 Kunihiro Ishiguro
4
 */
5
6
#include <zebra.h>
7
8
#include "prefix.h"
9
#include "frrevent.h"
10
#include "buffer.h"
11
#include "stream.h"
12
#include "ringbuf.h"
13
#include "command.h"
14
#include "sockunion.h"
15
#include "sockopt.h"
16
#include "network.h"
17
#include "memory.h"
18
#include "filter.h"
19
#include "routemap.h"
20
#include "log.h"
21
#include "plist.h"
22
#include "linklist.h"
23
#include "workqueue.h"
24
#include "queue.h"
25
#include "zclient.h"
26
#include "bfd.h"
27
#include "hash.h"
28
#include "jhash.h"
29
#include "table.h"
30
#include "lib/json.h"
31
#include "lib/sockopt.h"
32
#include "frr_pthread.h"
33
#include "bitfield.h"
34
35
#include "bgpd/bgpd.h"
36
#include "bgpd/bgp_table.h"
37
#include "bgpd/bgp_aspath.h"
38
#include "bgpd/bgp_route.h"
39
#include "bgpd/bgp_dump.h"
40
#include "bgpd/bgp_debug.h"
41
#include "bgpd/bgp_errors.h"
42
#include "bgpd/bgp_community.h"
43
#include "bgpd/bgp_community_alias.h"
44
#include "bgpd/bgp_conditional_adv.h"
45
#include "bgpd/bgp_attr.h"
46
#include "bgpd/bgp_regex.h"
47
#include "bgpd/bgp_clist.h"
48
#include "bgpd/bgp_fsm.h"
49
#include "bgpd/bgp_packet.h"
50
#include "bgpd/bgp_zebra.h"
51
#include "bgpd/bgp_open.h"
52
#include "bgpd/bgp_filter.h"
53
#include "bgpd/bgp_nexthop.h"
54
#include "bgpd/bgp_damp.h"
55
#include "bgpd/bgp_mplsvpn.h"
56
#ifdef ENABLE_BGP_VNC
57
#include "bgpd/rfapi/bgp_rfapi_cfg.h"
58
#include "bgpd/rfapi/rfapi_backend.h"
59
#endif
60
#include "bgpd/bgp_evpn.h"
61
#include "bgpd/bgp_advertise.h"
62
#include "bgpd/bgp_network.h"
63
#include "bgpd/bgp_vty.h"
64
#include "bgpd/bgp_mpath.h"
65
#include "bgpd/bgp_nht.h"
66
#include "bgpd/bgp_updgrp.h"
67
#include "bgpd/bgp_bfd.h"
68
#include "bgpd/bgp_memory.h"
69
#include "bgpd/bgp_evpn_vty.h"
70
#include "bgpd/bgp_keepalives.h"
71
#include "bgpd/bgp_io.h"
72
#include "bgpd/bgp_ecommunity.h"
73
#include "bgpd/bgp_flowspec.h"
74
#include "bgpd/bgp_labelpool.h"
75
#include "bgpd/bgp_pbr.h"
76
#include "bgpd/bgp_addpath.h"
77
#include "bgpd/bgp_evpn_private.h"
78
#include "bgpd/bgp_evpn_mh.h"
79
#include "bgpd/bgp_mac.h"
80
#include "bgp_trace.h"
81
82
DEFINE_MTYPE_STATIC(BGPD, PEER_TX_SHUTDOWN_MSG, "Peer shutdown message (TX)");
83
DEFINE_MTYPE_STATIC(BGPD, BGP_EVPN_INFO, "BGP EVPN instance information");
84
DEFINE_QOBJ_TYPE(bgp_master);
85
DEFINE_QOBJ_TYPE(bgp);
86
DEFINE_QOBJ_TYPE(peer);
87
DEFINE_HOOK(bgp_inst_delete, (struct bgp *bgp), (bgp));
88
89
/* BGP process wide configuration.  */
90
static struct bgp_master bgp_master;
91
92
/* BGP process wide configuration pointer to export.  */
93
struct bgp_master *bm;
94
95
/* BGP community-list.  */
96
struct community_list_handler *bgp_clist;
97
98
unsigned int multipath_num = MULTIPATH_NUM;
99
100
/* Number of bgp instances configured for suppress fib config */
101
unsigned int bgp_suppress_fib_count;
102
103
static void bgp_if_finish(struct bgp *bgp);
104
static void peer_drop_dynamic_neighbor(struct peer *peer);
105
106
extern struct zclient *zclient;
107
108
/* handle main socket creation or deletion */
109
static int bgp_check_main_socket(bool create, struct bgp *bgp)
110
0
{
111
0
  static int bgp_server_main_created;
112
0
  struct listnode *node;
113
0
  char *address;
114
115
0
  if (create) {
116
0
    if (bgp_server_main_created)
117
0
      return 0;
118
0
    if (list_isempty(bm->addresses)) {
119
0
      if (bgp_socket(bgp, bm->port, NULL) < 0)
120
0
        return BGP_ERR_INVALID_VALUE;
121
0
    } else {
122
0
      for (ALL_LIST_ELEMENTS_RO(bm->addresses, node, address))
123
0
        if (bgp_socket(bgp, bm->port, address) < 0)
124
0
          return BGP_ERR_INVALID_VALUE;
125
0
    }
126
0
    bgp_server_main_created = 1;
127
0
    return 0;
128
0
  }
129
0
  if (!bgp_server_main_created)
130
0
    return 0;
131
0
  bgp_close();
132
0
  bgp_server_main_created = 0;
133
0
  return 0;
134
0
}
135
136
void bgp_session_reset(struct peer *peer)
137
0
{
138
0
  if (peer->doppelganger && (peer->doppelganger->status != Deleted)
139
0
      && !(CHECK_FLAG(peer->doppelganger->flags, PEER_FLAG_CONFIG_NODE)))
140
0
    peer_delete(peer->doppelganger);
141
142
0
  BGP_EVENT_ADD(peer, BGP_Stop);
143
0
}
144
145
/*
146
 * During session reset, we may delete the doppelganger peer, which would
147
 * be the next node to the current node. If the session reset was invoked
148
 * during walk of peer list, we would end up accessing the freed next
149
 * node. This function moves the next node along.
150
 */
151
static void bgp_session_reset_safe(struct peer *peer, struct listnode **nnode)
152
0
{
153
0
  struct listnode *n;
154
0
  struct peer *npeer;
155
156
0
  n = (nnode) ? *nnode : NULL;
157
0
  npeer = (n) ? listgetdata(n) : NULL;
158
159
0
  if (peer->doppelganger && (peer->doppelganger->status != Deleted)
160
0
      && !(CHECK_FLAG(peer->doppelganger->flags,
161
0
          PEER_FLAG_CONFIG_NODE))) {
162
0
    if (peer->doppelganger == npeer)
163
      /* nnode and *nnode are confirmed to be non-NULL here */
164
0
      *nnode = (*nnode)->next;
165
0
    peer_delete(peer->doppelganger);
166
0
  }
167
168
0
  BGP_EVENT_ADD(peer, BGP_Stop);
169
0
}
170
171
/* BGP global flag manipulation.  */
172
int bgp_option_set(int flag)
173
3
{
174
3
  switch (flag) {
175
1
  case BGP_OPT_NO_FIB:
176
2
  case BGP_OPT_NO_LISTEN:
177
3
  case BGP_OPT_NO_ZEBRA:
178
3
    SET_FLAG(bm->options, flag);
179
3
    break;
180
0
  default:
181
0
    return BGP_ERR_INVALID_FLAG;
182
3
  }
183
3
  return 0;
184
3
}
185
186
int bgp_option_unset(int flag)
187
0
{
188
0
  switch (flag) {
189
  /* Fall through.  */
190
0
  case BGP_OPT_NO_ZEBRA:
191
0
  case BGP_OPT_NO_FIB:
192
0
    UNSET_FLAG(bm->options, flag);
193
0
    break;
194
0
  default:
195
0
    return BGP_ERR_INVALID_FLAG;
196
0
  }
197
0
  return 0;
198
0
}
199
200
int bgp_option_check(int flag)
201
1
{
202
1
  return CHECK_FLAG(bm->options, flag);
203
1
}
204
205
/* set the bgp no-rib option during runtime and remove installed routes */
206
void bgp_option_norib_set_runtime(void)
207
0
{
208
0
  struct bgp *bgp;
209
0
  struct listnode *node;
210
0
  afi_t afi;
211
0
  safi_t safi;
212
213
0
  if (bgp_option_check(BGP_OPT_NO_FIB))
214
0
    return;
215
216
0
  bgp_option_set(BGP_OPT_NO_FIB);
217
218
0
  zlog_info("Disabled BGP route installation to RIB (Zebra)");
219
220
0
  for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp)) {
221
0
    FOREACH_AFI_SAFI (afi, safi) {
222
      /*
223
       * Stop a crash, more work is needed
224
       * here to properly add/remove these types of
225
       * routes from zebra.
226
       */
227
0
      if (!bgp_fibupd_safi(safi))
228
0
        continue;
229
230
0
      bgp_zebra_withdraw_table_all_subtypes(bgp, afi, safi);
231
0
    }
232
0
  }
233
234
0
  zlog_info("All routes have been withdrawn from RIB (Zebra)");
235
0
}
236
237
/* unset the bgp no-rib option during runtime and announce routes to Zebra */
238
void bgp_option_norib_unset_runtime(void)
239
0
{
240
0
  struct bgp *bgp;
241
0
  struct listnode *node;
242
0
  afi_t afi;
243
0
  safi_t safi;
244
245
0
  if (!bgp_option_check(BGP_OPT_NO_FIB))
246
0
    return;
247
248
0
  bgp_option_unset(BGP_OPT_NO_FIB);
249
250
0
  zlog_info("Enabled BGP route installation to RIB (Zebra)");
251
252
0
  for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp)) {
253
0
    FOREACH_AFI_SAFI (afi, safi) {
254
      /*
255
       * Stop a crash, more work is needed
256
       * here to properly add/remove these types
257
       * of routes from zebra
258
       */
259
0
      if (!bgp_fibupd_safi(safi))
260
0
        continue;
261
262
0
      bgp_zebra_announce_table_all_subtypes(bgp, afi, safi);
263
0
    }
264
0
  }
265
266
0
  zlog_info("All routes have been installed in RIB (Zebra)");
267
0
}
268
269
/* Internal function to set BGP structure configureation flag.  */
270
static void bgp_config_set(struct bgp *bgp, int config)
271
0
{
272
0
  SET_FLAG(bgp->config, config);
273
0
}
274
275
static void bgp_config_unset(struct bgp *bgp, int config)
276
0
{
277
0
  UNSET_FLAG(bgp->config, config);
278
0
}
279
280
static int bgp_config_check(struct bgp *bgp, int config)
281
0
{
282
0
  return CHECK_FLAG(bgp->config, config);
283
0
}
284
285
/* Set BGP router identifier; distinguish between explicit config and other
286
 * cases.
287
 */
288
static int bgp_router_id_set(struct bgp *bgp, const struct in_addr *id,
289
           bool is_config)
290
1
{
291
1
  struct peer *peer;
292
1
  struct listnode *node, *nnode;
293
294
1
  if (IPV4_ADDR_SAME(&bgp->router_id, id))
295
1
    return 0;
296
297
  /* EVPN uses router id in RD, withdraw them */
298
0
  if (is_evpn_enabled())
299
0
    bgp_evpn_handle_router_id_update(bgp, true);
300
301
0
  vpn_handle_router_id_update(bgp, true, is_config);
302
303
0
  IPV4_ADDR_COPY(&bgp->router_id, id);
304
305
  /* Set all peer's local identifier with this value. */
306
0
  for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
307
0
    IPV4_ADDR_COPY(&peer->local_id, id);
308
309
0
    if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
310
0
      peer->last_reset = PEER_DOWN_RID_CHANGE;
311
0
      bgp_notify_send(peer, BGP_NOTIFY_CEASE,
312
0
          BGP_NOTIFY_CEASE_CONFIG_CHANGE);
313
0
    }
314
0
  }
315
316
  /* EVPN uses router id in RD, update them */
317
0
  if (is_evpn_enabled())
318
0
    bgp_evpn_handle_router_id_update(bgp, false);
319
320
0
  vpn_handle_router_id_update(bgp, false, is_config);
321
322
0
  return 0;
323
1
}
324
325
void bgp_router_id_zebra_bump(vrf_id_t vrf_id, const struct prefix *router_id)
326
0
{
327
0
  struct listnode *node, *nnode;
328
0
  struct bgp *bgp;
329
0
  struct in_addr *addr = NULL;
330
331
0
  if (router_id != NULL)
332
0
    addr = (struct in_addr *)&(router_id->u.prefix4);
333
334
0
  if (vrf_id == VRF_DEFAULT) {
335
    /* Router-id change for default VRF has to also update all
336
     * views. */
337
0
    for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
338
0
      if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
339
0
        continue;
340
341
0
      if (addr)
342
0
        bgp->router_id_zebra = *addr;
343
0
      else
344
0
        addr = &bgp->router_id_zebra;
345
346
0
      if (!bgp->router_id_static.s_addr) {
347
        /* Router ID is updated if there are no active
348
         * peer sessions
349
         */
350
0
        if (bgp->established_peers == 0) {
351
0
          if (BGP_DEBUG(zebra, ZEBRA))
352
0
            zlog_debug(
353
0
              "RID change : vrf %s(%u), RTR ID %pI4",
354
0
              bgp->name_pretty,
355
0
              bgp->vrf_id, addr);
356
          /*
357
           * if old router-id was 0x0, set flag
358
           * to use this new value
359
           */
360
0
          bgp_router_id_set(bgp, addr,
361
0
                (bgp->router_id.s_addr
362
0
                 == INADDR_ANY)
363
0
                  ? true
364
0
                  : false);
365
0
        }
366
0
      }
367
0
    }
368
0
  } else {
369
0
    bgp = bgp_lookup_by_vrf_id(vrf_id);
370
0
    if (bgp) {
371
0
      if (addr)
372
0
        bgp->router_id_zebra = *addr;
373
0
      else
374
0
        addr = &bgp->router_id_zebra;
375
376
0
      if (!bgp->router_id_static.s_addr) {
377
        /* Router ID is updated if there are no active
378
         * peer sessions
379
         */
380
0
        if (bgp->established_peers == 0) {
381
0
          if (BGP_DEBUG(zebra, ZEBRA))
382
0
            zlog_debug(
383
0
              "RID change : vrf %s(%u), RTR ID %pI4",
384
0
              bgp->name_pretty,
385
0
              bgp->vrf_id, addr);
386
          /*
387
           * if old router-id was 0x0, set flag
388
           * to use this new value
389
           */
390
0
          bgp_router_id_set(bgp, addr,
391
0
                (bgp->router_id.s_addr
392
0
                 == INADDR_ANY)
393
0
                  ? true
394
0
                  : false);
395
0
        }
396
0
      }
397
398
0
    }
399
0
  }
400
0
}
401
402
void bgp_router_id_static_set(struct bgp *bgp, struct in_addr id)
403
0
{
404
0
  bgp->router_id_static = id;
405
0
  bgp_router_id_set(bgp,
406
0
        id.s_addr != INADDR_ANY ? &id : &bgp->router_id_zebra,
407
0
        true /* is config */);
408
0
}
409
410
void bm_wait_for_fib_set(bool set)
411
0
{
412
0
  bool send_msg = false;
413
414
0
  if (bm->wait_for_fib == set)
415
0
    return;
416
417
0
  bm->wait_for_fib = set;
418
0
  if (set) {
419
0
    if (bgp_suppress_fib_count == 0)
420
0
      send_msg = true;
421
0
    bgp_suppress_fib_count++;
422
0
  } else {
423
0
    bgp_suppress_fib_count--;
424
0
    if (bgp_suppress_fib_count == 0)
425
0
      send_msg = true;
426
0
  }
427
428
0
  if (send_msg && zclient)
429
0
    zebra_route_notify_send(ZEBRA_ROUTE_NOTIFY_REQUEST,
430
0
          zclient, set);
431
0
}
432
433
/* Set the suppress fib pending for the bgp configuration */
434
void bgp_suppress_fib_pending_set(struct bgp *bgp, bool set)
435
0
{
436
0
  bool send_msg = false;
437
438
0
  if (bgp->inst_type == BGP_INSTANCE_TYPE_VIEW)
439
0
    return;
440
441
0
  if (set) {
442
0
    SET_FLAG(bgp->flags, BGP_FLAG_SUPPRESS_FIB_PENDING);
443
    /* Send msg to zebra for the first instance of bgp enabled
444
     * with suppress fib
445
     */
446
0
    if (bgp_suppress_fib_count == 0)
447
0
      send_msg = true;
448
0
    bgp_suppress_fib_count++;
449
0
  } else {
450
0
    UNSET_FLAG(bgp->flags, BGP_FLAG_SUPPRESS_FIB_PENDING);
451
0
    bgp_suppress_fib_count--;
452
453
    /* Send msg to zebra if there are no instances enabled
454
     * with suppress fib
455
     */
456
0
    if (bgp_suppress_fib_count == 0)
457
0
      send_msg = true;
458
0
  }
459
  /* Send route notify request to RIB */
460
0
  if (send_msg) {
461
0
    if (BGP_DEBUG(zebra, ZEBRA))
462
0
      zlog_debug("Sending ZEBRA_ROUTE_NOTIFY_REQUEST");
463
464
0
    if (zclient)
465
0
      zebra_route_notify_send(ZEBRA_ROUTE_NOTIFY_REQUEST,
466
0
          zclient, set);
467
0
  }
468
0
}
469
470
/* BGP's cluster-id control. */
471
void bgp_cluster_id_set(struct bgp *bgp, struct in_addr *cluster_id)
472
0
{
473
0
  struct peer *peer;
474
0
  struct listnode *node, *nnode;
475
476
0
  if (bgp_config_check(bgp, BGP_CONFIG_CLUSTER_ID)
477
0
      && IPV4_ADDR_SAME(&bgp->cluster_id, cluster_id))
478
0
    return;
479
480
0
  IPV4_ADDR_COPY(&bgp->cluster_id, cluster_id);
481
0
  bgp_config_set(bgp, BGP_CONFIG_CLUSTER_ID);
482
483
  /* Clear all IBGP peer. */
484
0
  for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
485
0
    if (peer->sort != BGP_PEER_IBGP)
486
0
      continue;
487
488
0
    if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
489
0
      peer->last_reset = PEER_DOWN_CLID_CHANGE;
490
0
      bgp_notify_send(peer, BGP_NOTIFY_CEASE,
491
0
          BGP_NOTIFY_CEASE_CONFIG_CHANGE);
492
0
    }
493
0
  }
494
0
}
495
496
void bgp_cluster_id_unset(struct bgp *bgp)
497
0
{
498
0
  struct peer *peer;
499
0
  struct listnode *node, *nnode;
500
501
0
  if (!bgp_config_check(bgp, BGP_CONFIG_CLUSTER_ID))
502
0
    return;
503
504
0
  bgp->cluster_id.s_addr = 0;
505
0
  bgp_config_unset(bgp, BGP_CONFIG_CLUSTER_ID);
506
507
  /* Clear all IBGP peer. */
508
0
  for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
509
0
    if (peer->sort != BGP_PEER_IBGP)
510
0
      continue;
511
512
0
    if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
513
0
      peer->last_reset = PEER_DOWN_CLID_CHANGE;
514
0
      bgp_notify_send(peer, BGP_NOTIFY_CEASE,
515
0
          BGP_NOTIFY_CEASE_CONFIG_CHANGE);
516
0
    }
517
0
  }
518
0
}
519
520
/* BGP timer configuration.  */
521
void bgp_timers_set(struct bgp *bgp, uint32_t keepalive, uint32_t holdtime,
522
        uint32_t connect_retry, uint32_t delayopen)
523
0
{
524
0
  bgp->default_keepalive =
525
0
    (keepalive < holdtime / 3 ? keepalive : holdtime / 3);
526
0
  bgp->default_holdtime = holdtime;
527
0
  bgp->default_connect_retry = connect_retry;
528
0
  bgp->default_delayopen = delayopen;
529
0
}
530
531
/* mostly for completeness - CLI uses its own defaults */
532
void bgp_timers_unset(struct bgp *bgp)
533
1
{
534
1
  bgp->default_keepalive = BGP_DEFAULT_KEEPALIVE;
535
1
  bgp->default_holdtime = BGP_DEFAULT_HOLDTIME;
536
1
  bgp->default_connect_retry = BGP_DEFAULT_CONNECT_RETRY;
537
1
  bgp->default_delayopen = BGP_DEFAULT_DELAYOPEN;
538
1
}
539
540
void bgp_tcp_keepalive_set(struct bgp *bgp, uint16_t keepalive_idle,
541
         uint16_t keepalive_intvl, uint16_t keepalive_probes)
542
0
{
543
0
  bgp->tcp_keepalive_idle = keepalive_idle;
544
0
  bgp->tcp_keepalive_intvl = keepalive_intvl;
545
0
  bgp->tcp_keepalive_probes = keepalive_probes;
546
0
}
547
548
void bgp_tcp_keepalive_unset(struct bgp *bgp)
549
1
{
550
1
  bgp->tcp_keepalive_idle = 0;
551
1
  bgp->tcp_keepalive_intvl = 0;
552
1
  bgp->tcp_keepalive_probes = 0;
553
1
}
554
555
/* BGP confederation configuration.  */
556
void bgp_confederation_id_set(struct bgp *bgp, as_t as, const char *as_str)
557
0
{
558
0
  struct peer *peer;
559
0
  struct listnode *node, *nnode;
560
0
  int already_confed;
561
562
0
  if (as == 0)
563
0
    return;
564
565
  /* Remember - were we doing confederation before? */
566
0
  already_confed = bgp_config_check(bgp, BGP_CONFIG_CONFEDERATION);
567
0
  bgp->confed_id = as;
568
0
  if (bgp->confed_id_pretty)
569
0
    XFREE(MTYPE_BGP, bgp->confed_id_pretty);
570
0
  bgp->confed_id_pretty = XSTRDUP(MTYPE_BGP, as_str);
571
0
  bgp_config_set(bgp, BGP_CONFIG_CONFEDERATION);
572
573
  /* If we were doing confederation already, this is just an external
574
     AS change.  Just Reset EBGP sessions, not CONFED sessions.  If we
575
     were not doing confederation before, reset all EBGP sessions.  */
576
0
  for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
577
0
    enum bgp_peer_sort ptype = peer_sort(peer);
578
579
    /* We're looking for peers who's AS is not local or part of our
580
       confederation.  */
581
0
    if (already_confed) {
582
0
      if (ptype == BGP_PEER_EBGP) {
583
0
        peer->local_as = as;
584
0
        if (BGP_IS_VALID_STATE_FOR_NOTIF(
585
0
              peer->status)) {
586
0
          peer->last_reset =
587
0
            PEER_DOWN_CONFED_ID_CHANGE;
588
0
          bgp_notify_send(
589
0
            peer, BGP_NOTIFY_CEASE,
590
0
            BGP_NOTIFY_CEASE_CONFIG_CHANGE);
591
0
        } else
592
0
          bgp_session_reset_safe(peer, &nnode);
593
0
      }
594
0
    } else {
595
      /* Not doign confederation before, so reset every
596
         non-local
597
         session */
598
0
      if (ptype != BGP_PEER_IBGP) {
599
        /* Reset the local_as to be our EBGP one */
600
0
        if (ptype == BGP_PEER_EBGP)
601
0
          peer->local_as = as;
602
0
        if (BGP_IS_VALID_STATE_FOR_NOTIF(
603
0
              peer->status)) {
604
0
          peer->last_reset =
605
0
            PEER_DOWN_CONFED_ID_CHANGE;
606
0
          bgp_notify_send(
607
0
            peer, BGP_NOTIFY_CEASE,
608
0
            BGP_NOTIFY_CEASE_CONFIG_CHANGE);
609
0
        } else
610
0
          bgp_session_reset_safe(peer, &nnode);
611
0
      }
612
0
    }
613
0
  }
614
0
  return;
615
0
}
616
617
void bgp_confederation_id_unset(struct bgp *bgp)
618
0
{
619
0
  struct peer *peer;
620
0
  struct listnode *node, *nnode;
621
622
0
  bgp->confed_id = 0;
623
0
  XFREE(MTYPE_BGP, bgp->confed_id_pretty);
624
0
  bgp_config_unset(bgp, BGP_CONFIG_CONFEDERATION);
625
626
0
  for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
627
    /* We're looking for peers who's AS is not local */
628
0
    if (peer_sort(peer) != BGP_PEER_IBGP) {
629
0
      peer->local_as = bgp->as;
630
0
      if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
631
0
        peer->last_reset = PEER_DOWN_CONFED_ID_CHANGE;
632
0
        bgp_notify_send(peer, BGP_NOTIFY_CEASE,
633
0
            BGP_NOTIFY_CEASE_CONFIG_CHANGE);
634
0
      }
635
636
0
      else
637
0
        bgp_session_reset_safe(peer, &nnode);
638
0
    }
639
0
  }
640
0
}
641
642
/* Is an AS part of the confed or not? */
643
bool bgp_confederation_peers_check(struct bgp *bgp, as_t as)
644
0
{
645
0
  int i;
646
647
0
  if (!bgp)
648
0
    return false;
649
650
0
  for (i = 0; i < bgp->confed_peers_cnt; i++)
651
0
    if (bgp->confed_peers[i].as == as)
652
0
      return true;
653
654
0
  return false;
655
0
}
656
657
/* Add an AS to the confederation set.  */
658
void bgp_confederation_peers_add(struct bgp *bgp, as_t as, const char *as_str)
659
0
{
660
0
  struct peer *peer;
661
0
  struct listnode *node, *nnode;
662
663
0
  if (!bgp)
664
0
    return;
665
666
0
  if (bgp_confederation_peers_check(bgp, as))
667
0
    return;
668
669
0
  bgp->confed_peers = XREALLOC(MTYPE_BGP_CONFED_LIST, bgp->confed_peers,
670
0
             (bgp->confed_peers_cnt + 1) *
671
0
               sizeof(struct as_confed));
672
673
0
  bgp->confed_peers[bgp->confed_peers_cnt].as = as;
674
0
  bgp->confed_peers[bgp->confed_peers_cnt].as_pretty =
675
0
    XSTRDUP(MTYPE_BGP, as_str);
676
0
  bgp->confed_peers_cnt++;
677
678
0
  if (bgp_config_check(bgp, BGP_CONFIG_CONFEDERATION)) {
679
0
    for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
680
0
      if (peer->as == as) {
681
0
        peer->local_as = bgp->as;
682
0
        (void)peer_sort(peer);
683
0
        if (BGP_IS_VALID_STATE_FOR_NOTIF(
684
0
              peer->status)) {
685
0
          peer->last_reset =
686
0
            PEER_DOWN_CONFED_PEER_CHANGE;
687
0
          bgp_notify_send(
688
0
            peer, BGP_NOTIFY_CEASE,
689
0
            BGP_NOTIFY_CEASE_CONFIG_CHANGE);
690
0
        } else
691
0
          bgp_session_reset_safe(peer, &nnode);
692
0
      }
693
0
    }
694
0
  }
695
0
}
696
697
/* Delete an AS from the confederation set.  */
698
void bgp_confederation_peers_remove(struct bgp *bgp, as_t as)
699
0
{
700
0
  int i;
701
0
  int j;
702
0
  struct peer *peer;
703
0
  struct listnode *node, *nnode;
704
705
0
  if (!bgp)
706
0
    return;
707
708
0
  if (!bgp_confederation_peers_check(bgp, as))
709
0
    return;
710
711
0
  for (i = 0; i < bgp->confed_peers_cnt; i++)
712
0
    if (bgp->confed_peers[i].as == as) {
713
0
      XFREE(MTYPE_BGP, bgp->confed_peers[i].as_pretty);
714
0
      for (j = i + 1; j < bgp->confed_peers_cnt; j++) {
715
0
        bgp->confed_peers[j - 1].as =
716
0
          bgp->confed_peers[j].as;
717
0
        bgp->confed_peers[j - 1].as_pretty =
718
0
          bgp->confed_peers[j].as_pretty;
719
0
      }
720
0
    }
721
722
0
  bgp->confed_peers_cnt--;
723
724
0
  if (bgp->confed_peers_cnt == 0) {
725
0
    if (bgp->confed_peers)
726
0
      XFREE(MTYPE_BGP_CONFED_LIST, bgp->confed_peers);
727
0
    bgp->confed_peers = NULL;
728
0
  } else
729
0
    bgp->confed_peers = XREALLOC(
730
0
      MTYPE_BGP_CONFED_LIST, bgp->confed_peers,
731
0
      bgp->confed_peers_cnt * sizeof(struct as_confed));
732
733
  /* Now reset any peer who's remote AS has just been removed from the
734
     CONFED */
735
0
  if (bgp_config_check(bgp, BGP_CONFIG_CONFEDERATION)) {
736
0
    for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
737
0
      if (peer->as == as) {
738
0
        peer->local_as = bgp->confed_id;
739
0
        (void)peer_sort(peer);
740
0
        if (BGP_IS_VALID_STATE_FOR_NOTIF(
741
0
              peer->status)) {
742
0
          peer->last_reset =
743
0
            PEER_DOWN_CONFED_PEER_CHANGE;
744
0
          bgp_notify_send(
745
0
            peer, BGP_NOTIFY_CEASE,
746
0
            BGP_NOTIFY_CEASE_CONFIG_CHANGE);
747
0
        } else
748
0
          bgp_session_reset_safe(peer, &nnode);
749
0
      }
750
0
    }
751
0
  }
752
0
}
753
754
/* Local preference configuration.  */
755
void bgp_default_local_preference_set(struct bgp *bgp, uint32_t local_pref)
756
0
{
757
0
  if (!bgp)
758
0
    return;
759
760
0
  bgp->default_local_pref = local_pref;
761
0
}
762
763
void bgp_default_local_preference_unset(struct bgp *bgp)
764
0
{
765
0
  if (!bgp)
766
0
    return;
767
768
0
  bgp->default_local_pref = BGP_DEFAULT_LOCAL_PREF;
769
0
}
770
771
/* Local preference configuration.  */
772
void bgp_default_subgroup_pkt_queue_max_set(struct bgp *bgp,
773
              uint32_t queue_size)
774
0
{
775
0
  if (!bgp)
776
0
    return;
777
778
0
  bgp->default_subgroup_pkt_queue_max = queue_size;
779
0
}
780
781
void bgp_default_subgroup_pkt_queue_max_unset(struct bgp *bgp)
782
0
{
783
0
  if (!bgp)
784
0
    return;
785
0
  bgp->default_subgroup_pkt_queue_max =
786
0
    BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX;
787
0
}
788
789
/* Listen limit configuration.  */
790
void bgp_listen_limit_set(struct bgp *bgp, int listen_limit)
791
0
{
792
0
  if (!bgp)
793
0
    return;
794
795
0
  bgp->dynamic_neighbors_limit = listen_limit;
796
0
}
797
798
void bgp_listen_limit_unset(struct bgp *bgp)
799
0
{
800
0
  if (!bgp)
801
0
    return;
802
803
0
  bgp->dynamic_neighbors_limit = BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT;
804
0
}
805
806
int bgp_map_afi_safi_iana2int(iana_afi_t pkt_afi, iana_safi_t pkt_safi,
807
            afi_t *afi, safi_t *safi)
808
468
{
809
  /* Map from IANA values to internal values, return error if
810
   * values are unrecognized.
811
   */
812
468
  *afi = afi_iana2int(pkt_afi);
813
468
  *safi = safi_iana2int(pkt_safi);
814
468
  if (*afi == AFI_MAX || *safi == SAFI_MAX)
815
151
    return -1;
816
817
317
  return 0;
818
468
}
819
820
int bgp_map_afi_safi_int2iana(afi_t afi, safi_t safi, iana_afi_t *pkt_afi,
821
            iana_safi_t *pkt_safi)
822
2
{
823
  /* Map from internal values to IANA values, return error if
824
   * internal values are bad (unexpected).
825
   */
826
2
  if (afi == AFI_MAX || safi == SAFI_MAX)
827
0
    return -1;
828
2
  *pkt_afi = afi_int2iana(afi);
829
2
  *pkt_safi = safi_int2iana(safi);
830
2
  return 0;
831
2
}
832
833
struct peer_af *peer_af_create(struct peer *peer, afi_t afi, safi_t safi)
834
3
{
835
3
  struct peer_af *af;
836
3
  int afid;
837
3
  struct bgp *bgp;
838
839
3
  if (!peer)
840
0
    return NULL;
841
842
3
  afid = afindex(afi, safi);
843
3
  if (afid >= BGP_AF_MAX)
844
0
    return NULL;
845
846
3
  bgp = peer->bgp;
847
3
  assert(peer->peer_af_array[afid] == NULL);
848
849
  /* Allocate new peer af */
850
3
  af = XCALLOC(MTYPE_BGP_PEER_AF, sizeof(struct peer_af));
851
852
3
  peer->peer_af_array[afid] = af;
853
3
  af->afi = afi;
854
3
  af->safi = safi;
855
3
  af->afid = afid;
856
3
  af->peer = peer;
857
3
  bgp->af_peer_count[afi][safi]++;
858
859
3
  return af;
860
3
}
861
862
struct peer_af *peer_af_find(struct peer *peer, afi_t afi, safi_t safi)
863
181
{
864
181
  int afid;
865
866
181
  if (!peer)
867
0
    return NULL;
868
869
181
  afid = afindex(afi, safi);
870
181
  if (afid >= BGP_AF_MAX)
871
26
    return NULL;
872
873
155
  return peer->peer_af_array[afid];
874
181
}
875
876
int peer_af_delete(struct peer *peer, afi_t afi, safi_t safi)
877
0
{
878
0
  struct peer_af *af;
879
0
  int afid;
880
0
  struct bgp *bgp;
881
882
0
  if (!peer)
883
0
    return -1;
884
885
0
  afid = afindex(afi, safi);
886
0
  if (afid >= BGP_AF_MAX)
887
0
    return -1;
888
889
0
  af = peer->peer_af_array[afid];
890
0
  if (!af)
891
0
    return -1;
892
893
0
  bgp = peer->bgp;
894
0
  bgp_soft_reconfig_table_task_cancel(bgp, bgp->rib[afi][safi], peer);
895
896
0
  bgp_stop_announce_route_timer(af);
897
898
0
  if (PAF_SUBGRP(af)) {
899
0
    if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
900
0
      zlog_debug("u%" PRIu64 ":s%" PRIu64 " remove peer %s",
901
0
           af->subgroup->update_group->id,
902
0
           af->subgroup->id, peer->host);
903
0
  }
904
905
906
0
  update_subgroup_remove_peer(af->subgroup, af);
907
908
0
  if (bgp->af_peer_count[afi][safi])
909
0
    bgp->af_peer_count[afi][safi]--;
910
911
0
  peer->peer_af_array[afid] = NULL;
912
0
  XFREE(MTYPE_BGP_PEER_AF, af);
913
0
  return 0;
914
0
}
915
916
/* Peer comparison function for sorting.  */
917
int peer_cmp(struct peer *p1, struct peer *p2)
918
0
{
919
0
  if (p1->group && !p2->group)
920
0
    return -1;
921
922
0
  if (!p1->group && p2->group)
923
0
    return 1;
924
925
0
  if (p1->group == p2->group) {
926
0
    if (p1->conf_if && !p2->conf_if)
927
0
      return -1;
928
929
0
    if (!p1->conf_if && p2->conf_if)
930
0
      return 1;
931
932
0
    if (p1->conf_if && p2->conf_if)
933
0
      return if_cmp_name_func(p1->conf_if, p2->conf_if);
934
0
  } else
935
0
    return strcmp(p1->group->name, p2->group->name);
936
937
0
  return sockunion_cmp(&p1->su, &p2->su);
938
0
}
939
940
static unsigned int peer_hash_key_make(const void *p)
941
1
{
942
1
  const struct peer *peer = p;
943
1
  return sockunion_hash(&peer->su);
944
1
}
945
946
static bool peer_hash_same(const void *p1, const void *p2)
947
0
{
948
0
  const struct peer *peer1 = p1;
949
0
  const struct peer *peer2 = p2;
950
951
0
  return (sockunion_same(&peer1->su, &peer2->su)
952
0
    && CHECK_FLAG(peer1->flags, PEER_FLAG_CONFIG_NODE)
953
0
         == CHECK_FLAG(peer2->flags, PEER_FLAG_CONFIG_NODE));
954
0
}
955
956
void peer_flag_inherit(struct peer *peer, uint64_t flag)
957
0
{
958
0
  bool group_val;
959
960
  /* Skip if peer is not a peer-group member. */
961
0
  if (!peer_group_active(peer))
962
0
    return;
963
964
  /* Unset override flag to signal inheritance from peer-group. */
965
0
  UNSET_FLAG(peer->flags_override, flag);
966
967
  /*
968
   * Inherit flag state from peer-group. If the flag of the peer-group is
969
   * not being inverted, the peer must inherit the inverse of the current
970
   * peer-group flag state.
971
   */
972
0
  group_val = CHECK_FLAG(peer->group->conf->flags, flag);
973
0
  if (!CHECK_FLAG(peer->group->conf->flags_invert, flag)
974
0
      && CHECK_FLAG(peer->flags_invert, flag))
975
0
    COND_FLAG(peer->flags, flag, !group_val);
976
0
  else
977
0
    COND_FLAG(peer->flags, flag, group_val);
978
0
}
979
980
bool peer_af_flag_check(struct peer *peer, afi_t afi, safi_t safi,
981
      uint64_t flag)
982
0
{
983
0
  return !!CHECK_FLAG(peer->af_flags[afi][safi], flag);
984
0
}
985
986
void peer_af_flag_inherit(struct peer *peer, afi_t afi, safi_t safi,
987
        uint64_t flag)
988
0
{
989
0
  bool group_val;
990
991
  /* Skip if peer is not a peer-group member. */
992
0
  if (!peer_group_active(peer))
993
0
    return;
994
995
  /* Unset override flag to signal inheritance from peer-group. */
996
0
  UNSET_FLAG(peer->af_flags_override[afi][safi], flag);
997
998
  /*
999
   * Inherit flag state from peer-group. If the flag of the peer-group is
1000
   * not being inverted, the peer must inherit the inverse of the current
1001
   * peer-group flag state.
1002
   */
1003
0
  group_val = CHECK_FLAG(peer->group->conf->af_flags[afi][safi], flag);
1004
0
  if (!CHECK_FLAG(peer->group->conf->af_flags_invert[afi][safi], flag)
1005
0
      && CHECK_FLAG(peer->af_flags_invert[afi][safi], flag))
1006
0
    COND_FLAG(peer->af_flags[afi][safi], flag, !group_val);
1007
0
  else
1008
0
    COND_FLAG(peer->af_flags[afi][safi], flag, group_val);
1009
0
}
1010
1011
/* Check peer's AS number and determines if this peer is IBGP or EBGP */
1012
static inline enum bgp_peer_sort peer_calc_sort(struct peer *peer)
1013
90
{
1014
90
  struct bgp *bgp;
1015
90
  as_t local_as;
1016
1017
90
  bgp = peer->bgp;
1018
1019
90
  if (peer->change_local_as)
1020
0
    local_as = peer->change_local_as;
1021
90
  else
1022
90
    local_as = peer->local_as;
1023
1024
  /* Peer-group */
1025
90
  if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
1026
0
    if (peer->as_type == AS_INTERNAL)
1027
0
      return BGP_PEER_IBGP;
1028
1029
0
    else if (peer->as_type == AS_EXTERNAL)
1030
0
      return BGP_PEER_EBGP;
1031
1032
0
    else if (peer->as_type == AS_SPECIFIED && peer->as) {
1033
0
      assert(bgp);
1034
0
      return (local_as == peer->as ? BGP_PEER_IBGP
1035
0
                 : BGP_PEER_EBGP);
1036
0
    }
1037
1038
0
    else {
1039
0
      struct peer *peer1;
1040
1041
0
      assert(peer->group);
1042
0
      peer1 = listnode_head(peer->group->peer);
1043
1044
0
      if (peer1)
1045
0
        return peer1->sort;
1046
0
    }
1047
0
    return BGP_PEER_INTERNAL;
1048
0
  }
1049
1050
  /* Normal peer */
1051
90
  if (bgp && CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
1052
0
    if (local_as == 0)
1053
0
      return BGP_PEER_INTERNAL;
1054
1055
0
    if (local_as == peer->as) {
1056
0
      if (bgp->as == bgp->confed_id) {
1057
0
        if (local_as == bgp->as)
1058
0
          return BGP_PEER_IBGP;
1059
0
        else
1060
0
          return BGP_PEER_EBGP;
1061
0
      } else {
1062
0
        if (local_as == bgp->confed_id)
1063
0
          return BGP_PEER_EBGP;
1064
0
        else
1065
0
          return BGP_PEER_IBGP;
1066
0
      }
1067
0
    }
1068
1069
0
    if (bgp_confederation_peers_check(bgp, peer->as))
1070
0
      return BGP_PEER_CONFED;
1071
1072
0
    return BGP_PEER_EBGP;
1073
90
  } else {
1074
90
    if (peer->as_type == AS_UNSPECIFIED) {
1075
      /* check if in peer-group with AS information */
1076
1
      if (peer->group
1077
1
          && (peer->group->conf->as_type != AS_UNSPECIFIED)) {
1078
0
        if (peer->group->conf->as_type
1079
0
            == AS_SPECIFIED) {
1080
0
          if (local_as == peer->group->conf->as)
1081
0
            return BGP_PEER_IBGP;
1082
0
          else
1083
0
            return BGP_PEER_EBGP;
1084
0
        } else if (peer->group->conf->as_type
1085
0
             == AS_INTERNAL)
1086
0
          return BGP_PEER_IBGP;
1087
0
        else
1088
0
          return BGP_PEER_EBGP;
1089
0
      }
1090
      /* no AS information anywhere, let caller know */
1091
1
      return BGP_PEER_UNSPECIFIED;
1092
89
    } else if (peer->as_type != AS_SPECIFIED)
1093
89
      return (peer->as_type == AS_INTERNAL ? BGP_PEER_IBGP
1094
89
                   : BGP_PEER_EBGP);
1095
1096
0
    return (local_as == 0 ? BGP_PEER_INTERNAL
1097
0
              : local_as == peer->as ? BGP_PEER_IBGP
1098
0
                   : BGP_PEER_EBGP);
1099
90
  }
1100
90
}
1101
1102
/* Calculate and cache the peer "sort" */
1103
enum bgp_peer_sort peer_sort(struct peer *peer)
1104
90
{
1105
90
  peer->sort = peer_calc_sort(peer);
1106
90
  return peer->sort;
1107
90
}
1108
1109
enum bgp_peer_sort peer_sort_lookup(struct peer *peer)
1110
0
{
1111
0
  return peer->sort;
1112
0
}
1113
1114
static void peer_free(struct peer *peer)
1115
0
{
1116
0
  afi_t afi;
1117
0
  safi_t safi;
1118
1119
0
  assert(peer->status == Deleted);
1120
1121
0
  QOBJ_UNREG(peer);
1122
1123
  /* this /ought/ to have been done already through bgp_stop earlier,
1124
   * but just to be sure..
1125
   */
1126
0
  bgp_timer_set(peer);
1127
0
  bgp_reads_off(peer);
1128
0
  bgp_writes_off(peer);
1129
0
  event_cancel_event_ready(bm->master, peer);
1130
0
  FOREACH_AFI_SAFI (afi, safi)
1131
0
    EVENT_OFF(peer->t_revalidate_all[afi][safi]);
1132
0
  assert(!peer->t_write);
1133
0
  assert(!peer->t_read);
1134
0
  BGP_EVENT_FLUSH(peer);
1135
1136
0
  pthread_mutex_destroy(&peer->io_mtx);
1137
1138
  /* Free connected nexthop, if present */
1139
0
  if (CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE)
1140
0
      && !peer_dynamic_neighbor(peer))
1141
0
    bgp_delete_connected_nexthop(family2afi(peer->su.sa.sa_family),
1142
0
               peer);
1143
1144
0
  FOREACH_AFI_SAFI (afi, safi) {
1145
0
    if (peer->filter[afi][safi].advmap.aname)
1146
0
      XFREE(MTYPE_BGP_FILTER_NAME,
1147
0
            peer->filter[afi][safi].advmap.aname);
1148
0
    if (peer->filter[afi][safi].advmap.cname)
1149
0
      XFREE(MTYPE_BGP_FILTER_NAME,
1150
0
            peer->filter[afi][safi].advmap.cname);
1151
0
  }
1152
1153
0
  XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG, peer->tx_shutdown_message);
1154
1155
0
  XFREE(MTYPE_PEER_DESC, peer->desc);
1156
0
  XFREE(MTYPE_BGP_PEER_HOST, peer->host);
1157
0
  XFREE(MTYPE_BGP_PEER_HOST, peer->hostname);
1158
0
  XFREE(MTYPE_BGP_PEER_HOST, peer->domainname);
1159
0
  XFREE(MTYPE_BGP_PEER_IFNAME, peer->ifname);
1160
1161
  /* Update source configuration.  */
1162
0
  if (peer->update_source) {
1163
0
    sockunion_free(peer->update_source);
1164
0
    peer->update_source = NULL;
1165
0
  }
1166
1167
0
  XFREE(MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
1168
1169
0
  XFREE(MTYPE_BGP_NOTIFICATION, peer->notify.data);
1170
0
  memset(&peer->notify, 0, sizeof(struct bgp_notify));
1171
1172
0
  if (peer->clear_node_queue)
1173
0
    work_queue_free_and_null(&peer->clear_node_queue);
1174
1175
0
  XFREE(MTYPE_PEER_CONF_IF, peer->conf_if);
1176
1177
0
  XFREE(MTYPE_BGP_SOFT_VERSION, peer->soft_version);
1178
1179
  /* Remove BFD configuration. */
1180
0
  if (peer->bfd_config)
1181
0
    bgp_peer_remove_bfd_config(peer);
1182
1183
0
  FOREACH_AFI_SAFI (afi, safi)
1184
0
    bgp_addpath_set_peer_type(peer, afi, safi, BGP_ADDPATH_NONE);
1185
1186
0
  if (peer->change_local_as_pretty)
1187
0
    XFREE(MTYPE_BGP, peer->change_local_as_pretty);
1188
0
  if (peer->as_pretty)
1189
0
    XFREE(MTYPE_BGP, peer->as_pretty);
1190
1191
0
  bgp_unlock(peer->bgp);
1192
1193
0
  stream_free(peer->last_reset_cause);
1194
1195
0
  memset(peer, 0, sizeof(struct peer));
1196
1197
0
  XFREE(MTYPE_BGP_PEER, peer);
1198
0
}
1199
1200
/* increase reference count on a struct peer */
1201
struct peer *peer_lock_with_caller(const char *name, struct peer *peer)
1202
8
{
1203
8
  frrtrace(2, frr_bgp, bgp_peer_lock, peer, name);
1204
8
  assert(peer && (peer->lock >= 0));
1205
1206
8
  peer->lock++;
1207
1208
8
  return peer;
1209
8
}
1210
1211
/* decrease reference count on a struct peer
1212
 * struct peer is freed and NULL returned if last reference
1213
 */
1214
struct peer *peer_unlock_with_caller(const char *name, struct peer *peer)
1215
5
{
1216
5
  frrtrace(2, frr_bgp, bgp_peer_unlock, peer, name);
1217
5
  assert(peer && (peer->lock > 0));
1218
1219
5
  peer->lock--;
1220
1221
5
  if (peer->lock == 0) {
1222
0
    peer_free(peer);
1223
0
    return NULL;
1224
0
  }
1225
1226
5
  return peer;
1227
5
}
1228
/* BGP GR changes */
1229
1230
int bgp_global_gr_init(struct bgp *bgp)
1231
1
{
1232
1
  if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
1233
0
    zlog_debug("%s called ..", __func__);
1234
1235
1
  int local_GLOBAL_GR_FSM[BGP_GLOBAL_GR_MODE][BGP_GLOBAL_GR_EVENT_CMD] = {
1236
    /* GLOBAL_HELPER Mode  */
1237
1
    {
1238
    /*Event -> */
1239
    /*GLOBAL_GR_cmd*/  /*no_Global_GR_cmd*/
1240
1
      GLOBAL_GR,      GLOBAL_INVALID,
1241
    /*GLOBAL_DISABLE_cmd*/ /*no_Global_Disable_cmd*/
1242
1
      GLOBAL_DISABLE, GLOBAL_INVALID
1243
1
    },
1244
    /* GLOBAL_GR Mode */
1245
1
    {
1246
    /*Event -> */
1247
    /*GLOBAL_GR_cmd*/ /*no_Global_GR_cmd*/
1248
1
      GLOBAL_GR,  GLOBAL_HELPER,
1249
    /*GLOBAL_DISABLE_cmd*/ /*no_Global_Disable_cmd*/
1250
1
      GLOBAL_DISABLE,  GLOBAL_INVALID
1251
1
    },
1252
    /* GLOBAL_DISABLE Mode  */
1253
1
    {
1254
    /*Event -> */
1255
    /*GLOBAL_GR_cmd */  /*no_Global_GR_cmd*/
1256
1
      GLOBAL_GR,      GLOBAL_INVALID,
1257
    /*GLOBAL_DISABLE_cmd*//*no_Global_Disable_cmd*/
1258
1
      GLOBAL_INVALID, GLOBAL_HELPER
1259
1
    },
1260
    /* GLOBAL_INVALID Mode  */
1261
1
    {
1262
    /*Event -> */
1263
    /*GLOBAL_GR_cmd*/ /*no_Global_GR_cmd*/
1264
1
      GLOBAL_INVALID, GLOBAL_INVALID,
1265
    /*GLOBAL_DISABLE_cmd*/ /*no_Global_Disable_cmd*/
1266
1
      GLOBAL_INVALID, GLOBAL_INVALID
1267
1
    }
1268
1
  };
1269
1
  memcpy(bgp->GLOBAL_GR_FSM, local_GLOBAL_GR_FSM,
1270
1
          sizeof(local_GLOBAL_GR_FSM));
1271
1272
1
  bgp->global_gr_present_state = GLOBAL_HELPER;
1273
1
  bgp->present_zebra_gr_state = ZEBRA_GR_DISABLE;
1274
1275
1
  return BGP_GR_SUCCESS;
1276
1
}
1277
1278
int bgp_peer_gr_init(struct peer *peer)
1279
2
{
1280
2
  if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
1281
0
    zlog_debug("%s called ..", __func__);
1282
1283
2
  struct bgp_peer_gr local_Peer_GR_FSM[BGP_PEER_GR_MODE]
1284
2
          [BGP_PEER_GR_EVENT_CMD] = {
1285
2
  {
1286
  /*  PEER_HELPER Mode  */
1287
  /* Event-> */ /* PEER_GR_CMD */ /* NO_PEER_GR_CMD */
1288
2
    { PEER_GR, bgp_peer_gr_action }, {PEER_INVALID, NULL },
1289
  /* Event-> */ /* PEER_DISABLE_CMD */ /* NO_PEER_DISABLE_CMD */
1290
2
    {PEER_DISABLE, bgp_peer_gr_action }, {PEER_INVALID, NULL },
1291
  /* Event-> */ /* PEER_HELPER_cmd */ /* NO_PEER_HELPER_CMD */
1292
2
    { PEER_INVALID, NULL }, {PEER_GLOBAL_INHERIT,
1293
2
            bgp_peer_gr_action }
1294
2
  },
1295
2
  {
1296
  /*  PEER_GR Mode  */
1297
  /* Event-> */ /* PEER_GR_CMD */ /* NO_PEER_GR_CMD */
1298
2
    { PEER_INVALID, NULL }, { PEER_GLOBAL_INHERIT,
1299
2
            bgp_peer_gr_action },
1300
  /* Event-> */ /* PEER_DISABLE_CMD */ /* NO_PEER_DISABLE_CMD */
1301
2
    {PEER_DISABLE, bgp_peer_gr_action }, { PEER_INVALID, NULL },
1302
  /* Event-> */ /* PEER_HELPER_cmd */ /* NO_PEER_HELPER_CMD */
1303
2
    { PEER_HELPER, bgp_peer_gr_action }, { PEER_INVALID, NULL }
1304
2
  },
1305
2
  {
1306
  /*  PEER_DISABLE Mode */
1307
  /* Event-> */ /* PEER_GR_CMD */ /* NO_PEER_GR_CMD */
1308
2
    { PEER_GR, bgp_peer_gr_action }, { PEER_INVALID, NULL },
1309
  /* Event-> */ /* PEER_DISABLE_CMD */ /* NO_PEER_DISABLE_CMD */
1310
2
    { PEER_INVALID, NULL }, { PEER_GLOBAL_INHERIT,
1311
2
            bgp_peer_gr_action },
1312
  /* Event-> */ /* PEER_HELPER_cmd */  /* NO_PEER_HELPER_CMD */
1313
2
    { PEER_HELPER, bgp_peer_gr_action }, { PEER_INVALID, NULL }
1314
2
  },
1315
2
  {
1316
  /*  PEER_INVALID Mode */
1317
  /* Event-> */ /* PEER_GR_CMD */  /* NO_PEER_GR_CMD */
1318
2
    { PEER_INVALID, NULL }, { PEER_INVALID, NULL },
1319
  /* Event-> */ /* PEER_DISABLE_CMD */  /* NO_PEER_DISABLE_CMD */
1320
2
    { PEER_INVALID, NULL }, { PEER_INVALID, NULL },
1321
  /* Event-> */ /* PEER_HELPER_cmd */  /* NO_PEER_HELPER_CMD */
1322
2
    { PEER_INVALID, NULL }, { PEER_INVALID, NULL },
1323
2
  },
1324
2
  {
1325
  /*  PEER_GLOBAL_INHERIT Mode  */
1326
  /* Event-> */ /* PEER_GR_CMD */   /* NO_PEER_GR_CMD */
1327
2
    { PEER_GR, bgp_peer_gr_action }, { PEER_INVALID, NULL },
1328
  /* Event-> */ /* PEER_DISABLE_CMD */     /* NO_PEER_DISABLE_CMD */
1329
2
    { PEER_DISABLE, bgp_peer_gr_action}, { PEER_INVALID, NULL },
1330
  /* Event-> */ /* PEER_HELPER_cmd */     /* NO_PEER_HELPER_CMD */
1331
2
    { PEER_HELPER, bgp_peer_gr_action }, { PEER_INVALID, NULL }
1332
2
  }
1333
2
  };
1334
2
  memcpy(&peer->PEER_GR_FSM, local_Peer_GR_FSM,
1335
2
          sizeof(local_Peer_GR_FSM));
1336
2
  peer->peer_gr_present_state = PEER_GLOBAL_INHERIT;
1337
2
  bgp_peer_move_to_gr_mode(peer, PEER_GLOBAL_INHERIT);
1338
1339
2
  return BGP_GR_SUCCESS;
1340
2
}
1341
1342
static void bgp_srv6_init(struct bgp *bgp)
1343
1
{
1344
1
  bgp->srv6_enabled = false;
1345
1
  memset(bgp->srv6_locator_name, 0, sizeof(bgp->srv6_locator_name));
1346
1
  bgp->srv6_locator_chunks = list_new();
1347
1
  bgp->srv6_functions = list_new();
1348
1
}
1349
1350
static void bgp_srv6_cleanup(struct bgp *bgp)
1351
0
{
1352
0
  if (bgp->srv6_locator_chunks)
1353
0
    list_delete(&bgp->srv6_locator_chunks);
1354
0
  if (bgp->srv6_functions)
1355
0
    list_delete(&bgp->srv6_functions);
1356
0
}
1357
1358
/* Allocate new peer object, implicitely locked.  */
1359
struct peer *peer_new(struct bgp *bgp)
1360
2
{
1361
2
  afi_t afi;
1362
2
  safi_t safi;
1363
2
  struct peer *peer;
1364
2
  struct servent *sp;
1365
1366
  /* bgp argument is absolutely required */
1367
2
  assert(bgp);
1368
1369
  /* Allocate new peer. */
1370
2
  peer = XCALLOC(MTYPE_BGP_PEER, sizeof(struct peer));
1371
1372
  /* Set default value. */
1373
2
  peer->fd = -1;
1374
2
  peer->v_start = BGP_INIT_START_TIMER;
1375
2
  peer->v_connect = bgp->default_connect_retry;
1376
2
  peer->status = Idle;
1377
2
  peer->ostatus = Idle;
1378
2
  peer->cur_event = peer->last_event = peer->last_major_event = 0;
1379
2
  peer->bgp = bgp_lock(bgp);
1380
2
  peer = peer_lock(peer); /* initial reference */
1381
2
  peer->local_role = ROLE_UNDEFINED;
1382
2
  peer->remote_role = ROLE_UNDEFINED;
1383
2
  peer->password = NULL;
1384
2
  peer->max_packet_size = BGP_STANDARD_MESSAGE_MAX_PACKET_SIZE;
1385
1386
  /* Set default flags. */
1387
42
  FOREACH_AFI_SAFI (afi, safi) {
1388
42
    SET_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY);
1389
42
    SET_FLAG(peer->af_flags[afi][safi],
1390
42
       PEER_FLAG_SEND_EXT_COMMUNITY);
1391
42
    SET_FLAG(peer->af_flags[afi][safi],
1392
42
       PEER_FLAG_SEND_LARGE_COMMUNITY);
1393
1394
42
    SET_FLAG(peer->af_flags_invert[afi][safi],
1395
42
       PEER_FLAG_SEND_COMMUNITY);
1396
42
    SET_FLAG(peer->af_flags_invert[afi][safi],
1397
42
       PEER_FLAG_SEND_EXT_COMMUNITY);
1398
42
    SET_FLAG(peer->af_flags_invert[afi][safi],
1399
42
       PEER_FLAG_SEND_LARGE_COMMUNITY);
1400
42
    peer->addpath_type[afi][safi] = BGP_ADDPATH_NONE;
1401
42
    peer->soo[afi][safi] = NULL;
1402
42
  }
1403
1404
  /* set nexthop-unchanged for l2vpn evpn by default */
1405
2
  SET_FLAG(peer->af_flags[AFI_L2VPN][SAFI_EVPN],
1406
2
     PEER_FLAG_NEXTHOP_UNCHANGED);
1407
1408
2
  SET_FLAG(peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
1409
1410
  /* Initialize per peer bgp GR FSM */
1411
2
  bgp_peer_gr_init(peer);
1412
1413
  /* Create buffers.  */
1414
2
  peer->ibuf = stream_fifo_new();
1415
2
  peer->obuf = stream_fifo_new();
1416
2
  pthread_mutex_init(&peer->io_mtx, NULL);
1417
1418
2
  peer->ibuf_work =
1419
2
    ringbuf_new(BGP_MAX_PACKET_SIZE + BGP_MAX_PACKET_SIZE/2);
1420
1421
  /* Get service port number.  */
1422
#ifndef FUZZING
1423
  sp = getservbyname("bgp", "tcp");
1424
#else
1425
2
  sp = NULL;
1426
2
#endif
1427
2
  peer->port = (sp == NULL) ? BGP_PORT_DEFAULT : ntohs(sp->s_port);
1428
1429
2
  QOBJ_REG(peer, peer);
1430
2
  return peer;
1431
2
}
1432
1433
/*
1434
 * This function is invoked when a duplicate peer structure associated with
1435
 * a neighbor is being deleted. If this about-to-be-deleted structure is
1436
 * the one with all the config, then we have to copy over the info.
1437
 */
1438
void peer_xfer_config(struct peer *peer_dst, struct peer *peer_src)
1439
0
{
1440
0
  struct peer_af *paf;
1441
0
  afi_t afi;
1442
0
  safi_t safi;
1443
0
  int afidx;
1444
1445
0
  assert(peer_src);
1446
0
  assert(peer_dst);
1447
1448
  /* The following function is used by both peer group config copy to
1449
   * individual peer and when we transfer config
1450
   */
1451
0
  if (peer_src->change_local_as)
1452
0
    peer_dst->change_local_as = peer_src->change_local_as;
1453
1454
  /* peer flags apply */
1455
0
  peer_dst->flags = peer_src->flags;
1456
  /*
1457
   * The doppelganger *must* not have a config node stored
1458
   */
1459
0
  UNSET_FLAG(peer_dst->flags, PEER_FLAG_CONFIG_NODE);
1460
0
  peer_dst->peer_gr_present_state = peer_src->peer_gr_present_state;
1461
0
  peer_dst->peer_gr_new_status_flag = peer_src->peer_gr_new_status_flag;
1462
1463
0
  peer_dst->local_as = peer_src->local_as;
1464
0
  peer_dst->port = peer_src->port;
1465
  /* copy tcp_mss value */
1466
0
  peer_dst->tcp_mss = peer_src->tcp_mss;
1467
0
  (void)peer_sort(peer_dst);
1468
0
  peer_dst->rmap_type = peer_src->rmap_type;
1469
0
  peer_dst->local_role = peer_src->local_role;
1470
1471
0
  peer_dst->max_packet_size = peer_src->max_packet_size;
1472
1473
  /* Timers */
1474
0
  peer_dst->holdtime = peer_src->holdtime;
1475
0
  peer_dst->keepalive = peer_src->keepalive;
1476
0
  peer_dst->connect = peer_src->connect;
1477
0
  peer_dst->delayopen = peer_src->delayopen;
1478
0
  peer_dst->v_holdtime = peer_src->v_holdtime;
1479
0
  peer_dst->v_keepalive = peer_src->v_keepalive;
1480
0
  peer_dst->routeadv = peer_src->routeadv;
1481
0
  peer_dst->v_routeadv = peer_src->v_routeadv;
1482
0
  peer_dst->v_delayopen = peer_src->v_delayopen;
1483
1484
  /* password apply */
1485
0
  if (peer_src->password) {
1486
0
    XFREE(MTYPE_PEER_PASSWORD, peer_dst->password);
1487
0
    peer_dst->password =
1488
0
      XSTRDUP(MTYPE_PEER_PASSWORD, peer_src->password);
1489
0
  }
1490
1491
0
  FOREACH_AFI_SAFI (afi, safi) {
1492
0
    peer_dst->afc[afi][safi] = peer_src->afc[afi][safi];
1493
0
    peer_dst->af_flags[afi][safi] = peer_src->af_flags[afi][safi];
1494
0
    peer_dst->allowas_in[afi][safi] =
1495
0
      peer_src->allowas_in[afi][safi];
1496
0
    peer_dst->weight[afi][safi] = peer_src->weight[afi][safi];
1497
0
    peer_dst->addpath_type[afi][safi] =
1498
0
      peer_src->addpath_type[afi][safi];
1499
0
  }
1500
1501
0
  for (afidx = BGP_AF_START; afidx < BGP_AF_MAX; afidx++) {
1502
0
    paf = peer_src->peer_af_array[afidx];
1503
0
    if (paf != NULL) {
1504
0
      if (!peer_af_find(peer_dst, paf->afi, paf->safi))
1505
0
        peer_af_create(peer_dst, paf->afi, paf->safi);
1506
0
    }
1507
0
  }
1508
1509
  /* update-source apply */
1510
0
  if (peer_src->update_source) {
1511
0
    if (peer_dst->update_source)
1512
0
      sockunion_free(peer_dst->update_source);
1513
0
    XFREE(MTYPE_PEER_UPDATE_SOURCE, peer_dst->update_if);
1514
0
    peer_dst->update_source =
1515
0
      sockunion_dup(peer_src->update_source);
1516
0
  } else if (peer_src->update_if) {
1517
0
    XFREE(MTYPE_PEER_UPDATE_SOURCE, peer_dst->update_if);
1518
0
    if (peer_dst->update_source) {
1519
0
      sockunion_free(peer_dst->update_source);
1520
0
      peer_dst->update_source = NULL;
1521
0
    }
1522
0
    peer_dst->update_if =
1523
0
      XSTRDUP(MTYPE_PEER_UPDATE_SOURCE, peer_src->update_if);
1524
0
  }
1525
1526
0
  if (peer_src->ifname) {
1527
0
    XFREE(MTYPE_BGP_PEER_IFNAME, peer_dst->ifname);
1528
1529
0
    peer_dst->ifname =
1530
0
      XSTRDUP(MTYPE_BGP_PEER_IFNAME, peer_src->ifname);
1531
0
  }
1532
0
  peer_dst->ttl = peer_src->ttl;
1533
0
}
1534
1535
static int bgp_peer_conf_if_to_su_update_v4(struct peer *peer,
1536
              struct interface *ifp)
1537
0
{
1538
0
  struct connected *ifc;
1539
0
  struct prefix p;
1540
0
  uint32_t addr;
1541
0
  struct listnode *node;
1542
1543
  /* If our IPv4 address on the interface is /30 or /31, we can derive the
1544
   * IPv4 address of the other end.
1545
   */
1546
0
  for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
1547
0
    if (ifc->address && (ifc->address->family == AF_INET)) {
1548
0
      prefix_copy(&p, CONNECTED_PREFIX(ifc));
1549
0
      if (p.prefixlen == 30) {
1550
0
        peer->su.sa.sa_family = AF_INET;
1551
0
        addr = ntohl(p.u.prefix4.s_addr);
1552
0
        if (addr % 4 == 1)
1553
0
          peer->su.sin.sin_addr.s_addr =
1554
0
            htonl(addr + 1);
1555
0
        else if (addr % 4 == 2)
1556
0
          peer->su.sin.sin_addr.s_addr =
1557
0
            htonl(addr - 1);
1558
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1559
        peer->su.sin.sin_len =
1560
          sizeof(struct sockaddr_in);
1561
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1562
0
        return 1;
1563
0
      } else if (p.prefixlen == 31) {
1564
0
        peer->su.sa.sa_family = AF_INET;
1565
0
        addr = ntohl(p.u.prefix4.s_addr);
1566
0
        if (addr % 2 == 0)
1567
0
          peer->su.sin.sin_addr.s_addr =
1568
0
            htonl(addr + 1);
1569
0
        else
1570
0
          peer->su.sin.sin_addr.s_addr =
1571
0
            htonl(addr - 1);
1572
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1573
        peer->su.sin.sin_len =
1574
          sizeof(struct sockaddr_in);
1575
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1576
0
        return 1;
1577
0
      } else if (bgp_debug_neighbor_events(peer))
1578
0
        zlog_debug(
1579
0
          "%s: IPv4 interface address is not /30 or /31, v4 session not started",
1580
0
          peer->conf_if);
1581
0
    }
1582
0
  }
1583
1584
0
  return 0;
1585
0
}
1586
1587
static bool bgp_peer_conf_if_to_su_update_v6(struct peer *peer,
1588
               struct interface *ifp)
1589
0
{
1590
0
  struct nbr_connected *ifc_nbr;
1591
1592
  /* Have we learnt the peer's IPv6 link-local address? */
1593
0
  if (ifp->nbr_connected
1594
0
      && (ifc_nbr = listnode_head(ifp->nbr_connected))) {
1595
0
    peer->su.sa.sa_family = AF_INET6;
1596
0
    memcpy(&peer->su.sin6.sin6_addr, &ifc_nbr->address->u.prefix,
1597
0
           sizeof(struct in6_addr));
1598
#ifdef SIN6_LEN
1599
    peer->su.sin6.sin6_len = sizeof(struct sockaddr_in6);
1600
#endif
1601
0
    peer->su.sin6.sin6_scope_id = ifp->ifindex;
1602
0
    return true;
1603
0
  }
1604
1605
0
  return false;
1606
0
}
1607
1608
/*
1609
 * Set or reset the peer address socketunion structure based on the
1610
 * learnt/derived peer address. If the address has changed, update the
1611
 * password on the listen socket, if needed.
1612
 */
1613
void bgp_peer_conf_if_to_su_update(struct peer *peer)
1614
0
{
1615
0
  struct interface *ifp;
1616
0
  int prev_family;
1617
0
  int peer_addr_updated = 0;
1618
0
  struct listnode *node;
1619
0
  union sockunion old_su;
1620
1621
  /*
1622
   * This function is only ever needed when FRR an interface
1623
   * based peering, so this simple test will tell us if
1624
   * we are in an interface based configuration or not
1625
   */
1626
0
  if (!peer->conf_if)
1627
0
    return;
1628
1629
0
  old_su = peer->su;
1630
1631
0
  prev_family = peer->su.sa.sa_family;
1632
0
  if ((ifp = if_lookup_by_name(peer->conf_if, peer->bgp->vrf_id))) {
1633
0
    peer->ifp = ifp;
1634
    /* If BGP unnumbered is not "v6only", we first see if we can
1635
     * derive the
1636
     * peer's IPv4 address.
1637
     */
1638
0
    if (!CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY))
1639
0
      peer_addr_updated =
1640
0
        bgp_peer_conf_if_to_su_update_v4(peer, ifp);
1641
1642
    /* If "v6only" or we can't derive peer's IPv4 address, see if
1643
     * we've
1644
     * learnt the peer's IPv6 link-local address. This is from the
1645
     * source
1646
     * IPv6 address in router advertisement.
1647
     */
1648
0
    if (!peer_addr_updated)
1649
0
      peer_addr_updated =
1650
0
        bgp_peer_conf_if_to_su_update_v6(peer, ifp);
1651
0
  }
1652
  /* If we could derive the peer address, we may need to install the
1653
   * password
1654
   * configured for the peer, if any, on the listen socket. Otherwise,
1655
   * mark
1656
   * that peer's address is not available and uninstall the password, if
1657
   * needed.
1658
   */
1659
0
  if (peer_addr_updated) {
1660
0
    if (CHECK_FLAG(peer->flags, PEER_FLAG_PASSWORD)
1661
0
        && prev_family == AF_UNSPEC)
1662
0
      bgp_md5_set(peer);
1663
0
  } else {
1664
0
    if (CHECK_FLAG(peer->flags, PEER_FLAG_PASSWORD)
1665
0
        && prev_family != AF_UNSPEC)
1666
0
      bgp_md5_unset(peer);
1667
0
    peer->su.sa.sa_family = AF_UNSPEC;
1668
0
    memset(&peer->su.sin6.sin6_addr, 0, sizeof(struct in6_addr));
1669
0
  }
1670
1671
  /*
1672
   * If they are the same, nothing to do here, move along
1673
   */
1674
0
  if (!sockunion_same(&old_su, &peer->su)) {
1675
0
    union sockunion new_su = peer->su;
1676
0
    struct bgp *bgp = peer->bgp;
1677
1678
    /*
1679
     * Our peer structure is stored in the bgp->peerhash
1680
     * release it before we modify anything in both the
1681
     * hash and the list.  But *only* if the peer
1682
     * is in the bgp->peerhash as that on deletion
1683
     * we call bgp_stop which calls this function :(
1684
     * so on deletion let's remove from the list first
1685
     * and then do the deletion preventing this from
1686
     * being added back on the list below when we
1687
     * fail to remove it up here.
1688
     */
1689
1690
    /*
1691
     * listnode_lookup just scans the list
1692
     * for the peer structure so it's safe
1693
     * to use without modifying the su
1694
     */
1695
0
    node = listnode_lookup(bgp->peer, peer);
1696
0
    if (node) {
1697
      /*
1698
       * Let's reset the peer->su release and
1699
       * reset it and put it back.  We have to
1700
       * do this because hash_release will
1701
       * scan through looking for a matching
1702
       * su if needed.
1703
       */
1704
0
      peer->su = old_su;
1705
0
      hash_release(peer->bgp->peerhash, peer);
1706
0
      listnode_delete(peer->bgp->peer, peer);
1707
1708
0
      peer->su = new_su;
1709
0
      (void)hash_get(peer->bgp->peerhash, peer,
1710
0
               hash_alloc_intern);
1711
0
      listnode_add_sort(peer->bgp->peer, peer);
1712
0
    }
1713
0
  }
1714
0
}
1715
1716
void bgp_recalculate_afi_safi_bestpaths(struct bgp *bgp, afi_t afi, safi_t safi)
1717
0
{
1718
0
  struct bgp_dest *dest, *ndest;
1719
0
  struct bgp_table *table;
1720
1721
0
  for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
1722
0
       dest = bgp_route_next(dest)) {
1723
0
    table = bgp_dest_get_bgp_table_info(dest);
1724
0
    if (table != NULL) {
1725
      /* Special handling for 2-level routing
1726
       * tables. */
1727
0
      if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
1728
0
          || safi == SAFI_EVPN) {
1729
0
        for (ndest = bgp_table_top(table); ndest;
1730
0
             ndest = bgp_route_next(ndest))
1731
0
          bgp_process(bgp, ndest, afi, safi);
1732
0
      } else
1733
0
        bgp_process(bgp, dest, afi, safi);
1734
0
    }
1735
0
  }
1736
0
}
1737
1738
/* Force a bestpath recalculation for all prefixes.  This is used
1739
 * when 'bgp bestpath' commands are entered.
1740
 */
1741
void bgp_recalculate_all_bestpaths(struct bgp *bgp)
1742
0
{
1743
0
  afi_t afi;
1744
0
  safi_t safi;
1745
1746
0
  FOREACH_AFI_SAFI (afi, safi) {
1747
0
    bgp_recalculate_afi_safi_bestpaths(bgp, afi, safi);
1748
0
  }
1749
0
}
1750
1751
/*
1752
 * Create new BGP peer.
1753
 *
1754
 * conf_if and su are mutually exclusive if configuring from the cli.
1755
 * If we are handing a doppelganger, then we *must* pass in both
1756
 * the original peer's su and conf_if, so that we can appropriately
1757
 * track the bgp->peerhash( ie we don't want to remove the current
1758
 * one from the config ).
1759
 */
1760
struct peer *peer_create(union sockunion *su, const char *conf_if,
1761
       struct bgp *bgp, as_t local_as, as_t remote_as,
1762
       int as_type, struct peer_group *group,
1763
       bool config_node, const char *as_str)
1764
1
{
1765
1
  int active;
1766
1
  struct peer *peer;
1767
1
  char buf[SU_ADDRSTRLEN];
1768
1
  afi_t afi;
1769
1
  safi_t safi;
1770
1771
1
  peer = peer_new(bgp);
1772
1
  if (conf_if) {
1773
0
    peer->conf_if = XSTRDUP(MTYPE_PEER_CONF_IF, conf_if);
1774
0
    if (su)
1775
0
      peer->su = *su;
1776
0
    else
1777
0
      bgp_peer_conf_if_to_su_update(peer);
1778
0
    XFREE(MTYPE_BGP_PEER_HOST, peer->host);
1779
0
    peer->host = XSTRDUP(MTYPE_BGP_PEER_HOST, conf_if);
1780
1
  } else if (su) {
1781
1
    peer->su = *su;
1782
1
    sockunion2str(su, buf, SU_ADDRSTRLEN);
1783
1
    XFREE(MTYPE_BGP_PEER_HOST, peer->host);
1784
1
    peer->host = XSTRDUP(MTYPE_BGP_PEER_HOST, buf);
1785
1
  }
1786
1
  peer->local_as = local_as;
1787
1
  peer->as = remote_as;
1788
  /* internal and external values do not use as_pretty */
1789
1
  if (as_str && asn_str2asn(as_str, NULL))
1790
0
    peer->as_pretty = XSTRDUP(MTYPE_BGP, as_str);
1791
1
  peer->as_type = as_type;
1792
1
  peer->local_id = bgp->router_id;
1793
1
  peer->v_holdtime = bgp->default_holdtime;
1794
1
  peer->v_keepalive = bgp->default_keepalive;
1795
1
  peer->v_routeadv = (peer_sort(peer) == BGP_PEER_IBGP)
1796
1
           ? BGP_DEFAULT_IBGP_ROUTEADV
1797
1
           : BGP_DEFAULT_EBGP_ROUTEADV;
1798
1
  if (bgp_config_inprocess())
1799
0
    peer->shut_during_cfg = true;
1800
1801
1
  peer = peer_lock(peer); /* bgp peer list reference */
1802
1
  peer->group = group;
1803
1
  listnode_add_sort(bgp->peer, peer);
1804
1805
1
  if (config_node)
1806
1
    SET_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE);
1807
1808
1
  (void)hash_get(bgp->peerhash, peer, hash_alloc_intern);
1809
1810
  /* Adjust update-group coalesce timer heuristics for # peers. */
1811
1
  if (bgp->heuristic_coalesce) {
1812
1
    long ct = BGP_DEFAULT_SUBGROUP_COALESCE_TIME
1813
1
        + (bgp->peer->count
1814
1
           * BGP_PEER_ADJUST_SUBGROUP_COALESCE_TIME);
1815
1
    bgp->coalesce_time = MIN(BGP_MAX_SUBGROUP_COALESCE_TIME, ct);
1816
1
  }
1817
1818
1
  active = peer_active(peer);
1819
1
  if (!active) {
1820
1
    if (peer->su.sa.sa_family == AF_UNSPEC)
1821
0
      peer->last_reset = PEER_DOWN_NBR_ADDR;
1822
1
    else
1823
1
      peer->last_reset = PEER_DOWN_NOAFI_ACTIVATED;
1824
1
  }
1825
1826
  /* Last read and reset time set */
1827
1
  peer->readtime = peer->resettime = monotime(NULL);
1828
1829
  /* Default TTL set. */
1830
1
  peer->ttl = (peer->sort == BGP_PEER_IBGP) ? MAXTTL : BGP_DEFAULT_TTL;
1831
1832
  /* Default configured keepalives count for shutdown rtt command */
1833
1
  peer->rtt_keepalive_conf = 1;
1834
1835
  /* If 'bgp default <afi>-<safi>' is configured, then activate the
1836
   * neighbor for the corresponding address family. IPv4 Unicast is
1837
   * the only address family enabled by default without expliict
1838
   * configuration.
1839
   */
1840
21
  FOREACH_AFI_SAFI (afi, safi) {
1841
21
    if (bgp->default_af[afi][safi]) {
1842
1
      peer->afc[afi][safi] = 1;
1843
1
      peer_af_create(peer, afi, safi);
1844
1
    }
1845
21
  }
1846
1847
  /* auto shutdown if configured */
1848
1
  if (bgp->autoshutdown)
1849
0
    peer_flag_set(peer, PEER_FLAG_SHUTDOWN);
1850
  /* Set up peer's events and timers. */
1851
1
  else if (!active && peer_active(peer))
1852
1
    bgp_timer_set(peer);
1853
1854
1
  bgp_peer_gr_flags_update(peer);
1855
1
  BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(bgp, bgp->peer);
1856
1857
0
  return peer;
1858
1
}
1859
1860
/* Make accept BGP peer. This function is only called from the test code */
1861
struct peer *peer_create_accept(struct bgp *bgp)
1862
0
{
1863
0
  struct peer *peer;
1864
1865
0
  peer = peer_new(bgp);
1866
1867
0
  peer = peer_lock(peer); /* bgp peer list reference */
1868
0
  listnode_add_sort(bgp->peer, peer);
1869
0
  (void)hash_get(bgp->peerhash, peer, hash_alloc_intern);
1870
1871
0
  return peer;
1872
0
}
1873
1874
/*
1875
 * Return true if we have a peer configured to use this afi/safi
1876
 */
1877
bool bgp_afi_safi_peer_exists(struct bgp *bgp, afi_t afi, safi_t safi)
1878
0
{
1879
0
  struct listnode *node;
1880
0
  struct peer *peer;
1881
1882
0
  for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer)) {
1883
0
    if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
1884
0
      continue;
1885
1886
0
    if (peer->afc[afi][safi])
1887
0
      return true;
1888
0
  }
1889
1890
0
  return false;
1891
0
}
1892
1893
/* Change peer's AS number.  */
1894
void peer_as_change(struct peer *peer, as_t as, int as_specified,
1895
        const char *as_str)
1896
0
{
1897
0
  enum bgp_peer_sort origtype, newtype;
1898
1899
  /* Stop peer. */
1900
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
1901
0
    if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
1902
0
      peer->last_reset = PEER_DOWN_REMOTE_AS_CHANGE;
1903
0
      bgp_notify_send(peer, BGP_NOTIFY_CEASE,
1904
0
          BGP_NOTIFY_CEASE_CONFIG_CHANGE);
1905
0
    } else
1906
0
      bgp_session_reset(peer);
1907
0
  }
1908
0
  origtype = peer_sort_lookup(peer);
1909
0
  peer->as = as;
1910
0
  if (as_specified == AS_SPECIFIED && as_str) {
1911
0
    if (peer->as_pretty)
1912
0
      XFREE(MTYPE_BGP, peer->as_pretty);
1913
0
    peer->as_pretty = XSTRDUP(MTYPE_BGP, as_str);
1914
0
  } else if (peer->as_type == AS_UNSPECIFIED && peer->as_pretty)
1915
0
    XFREE(MTYPE_BGP, peer->as_pretty);
1916
0
  peer->as_type = as_specified;
1917
1918
0
  if (bgp_config_check(peer->bgp, BGP_CONFIG_CONFEDERATION)
1919
0
      && !bgp_confederation_peers_check(peer->bgp, as)
1920
0
      && peer->bgp->as != as)
1921
0
    peer->local_as = peer->bgp->confed_id;
1922
0
  else
1923
0
    peer->local_as = peer->bgp->as;
1924
1925
0
  newtype = peer_sort(peer);
1926
  /* Advertisement-interval reset */
1927
0
  if (!CHECK_FLAG(peer->flags, PEER_FLAG_ROUTEADV)) {
1928
0
    peer->v_routeadv = (newtype == BGP_PEER_IBGP)
1929
0
             ? BGP_DEFAULT_IBGP_ROUTEADV
1930
0
             : BGP_DEFAULT_EBGP_ROUTEADV;
1931
0
  }
1932
1933
  /* TTL reset */
1934
0
  if (newtype == BGP_PEER_IBGP)
1935
0
    peer->ttl = MAXTTL;
1936
0
  else if (origtype == BGP_PEER_IBGP)
1937
0
    peer->ttl = BGP_DEFAULT_TTL;
1938
1939
  /* reflector-client reset */
1940
0
  if (newtype != BGP_PEER_IBGP) {
1941
0
    UNSET_FLAG(peer->af_flags[AFI_IP][SAFI_UNICAST],
1942
0
         PEER_FLAG_REFLECTOR_CLIENT);
1943
0
    UNSET_FLAG(peer->af_flags[AFI_IP][SAFI_MULTICAST],
1944
0
         PEER_FLAG_REFLECTOR_CLIENT);
1945
0
    UNSET_FLAG(peer->af_flags[AFI_IP][SAFI_LABELED_UNICAST],
1946
0
         PEER_FLAG_REFLECTOR_CLIENT);
1947
0
    UNSET_FLAG(peer->af_flags[AFI_IP][SAFI_MPLS_VPN],
1948
0
         PEER_FLAG_REFLECTOR_CLIENT);
1949
0
    UNSET_FLAG(peer->af_flags[AFI_IP][SAFI_ENCAP],
1950
0
         PEER_FLAG_REFLECTOR_CLIENT);
1951
0
    UNSET_FLAG(peer->af_flags[AFI_IP][SAFI_FLOWSPEC],
1952
0
         PEER_FLAG_REFLECTOR_CLIENT);
1953
0
    UNSET_FLAG(peer->af_flags[AFI_IP6][SAFI_UNICAST],
1954
0
         PEER_FLAG_REFLECTOR_CLIENT);
1955
0
    UNSET_FLAG(peer->af_flags[AFI_IP6][SAFI_MULTICAST],
1956
0
         PEER_FLAG_REFLECTOR_CLIENT);
1957
0
    UNSET_FLAG(peer->af_flags[AFI_IP6][SAFI_LABELED_UNICAST],
1958
0
         PEER_FLAG_REFLECTOR_CLIENT);
1959
0
    UNSET_FLAG(peer->af_flags[AFI_IP6][SAFI_MPLS_VPN],
1960
0
         PEER_FLAG_REFLECTOR_CLIENT);
1961
0
    UNSET_FLAG(peer->af_flags[AFI_IP6][SAFI_ENCAP],
1962
0
         PEER_FLAG_REFLECTOR_CLIENT);
1963
0
    UNSET_FLAG(peer->af_flags[AFI_IP6][SAFI_FLOWSPEC],
1964
0
         PEER_FLAG_REFLECTOR_CLIENT);
1965
0
    UNSET_FLAG(peer->af_flags[AFI_L2VPN][SAFI_EVPN],
1966
0
         PEER_FLAG_REFLECTOR_CLIENT);
1967
0
  }
1968
0
}
1969
1970
/* If peer does not exist, create new one.  If peer already exists,
1971
   set AS number to the peer.  */
1972
int peer_remote_as(struct bgp *bgp, union sockunion *su, const char *conf_if,
1973
       as_t *as, int as_type, const char *as_str)
1974
0
{
1975
0
  struct peer *peer;
1976
0
  as_t local_as;
1977
1978
0
  if (conf_if)
1979
0
    peer = peer_lookup_by_conf_if(bgp, conf_if);
1980
0
  else
1981
0
    peer = peer_lookup(bgp, su);
1982
1983
0
  if (peer) {
1984
    /* Not allowed for a dynamic peer. */
1985
0
    if (peer_dynamic_neighbor(peer)) {
1986
0
      *as = peer->as;
1987
0
      return BGP_ERR_INVALID_FOR_DYNAMIC_PEER;
1988
0
    }
1989
1990
    /* When this peer is a member of peer-group.  */
1991
0
    if (peer->group) {
1992
      /* peer-group already has AS number/internal/external */
1993
0
      if (peer->group->conf->as
1994
0
          || peer->group->conf->as_type) {
1995
        /* Return peer group's AS number.  */
1996
0
        *as = peer->group->conf->as;
1997
0
        return BGP_ERR_PEER_GROUP_MEMBER;
1998
0
      }
1999
2000
0
      enum bgp_peer_sort peer_sort_type =
2001
0
        peer_sort(peer->group->conf);
2002
2003
      /* Explicit AS numbers used, compare AS numbers */
2004
0
      if (as_type == AS_SPECIFIED) {
2005
0
        if (((peer_sort_type == BGP_PEER_IBGP)
2006
0
            && (bgp->as != *as))
2007
0
            || ((peer_sort_type == BGP_PEER_EBGP)
2008
0
            && (bgp->as == *as))) {
2009
0
          *as = peer->as;
2010
0
          return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT;
2011
0
        }
2012
0
      } else {
2013
        /* internal/external used, compare as-types */
2014
0
        if (((peer_sort_type == BGP_PEER_IBGP)
2015
0
            && (as_type != AS_INTERNAL))
2016
0
            || ((peer_sort_type == BGP_PEER_EBGP)
2017
0
            && (as_type != AS_EXTERNAL)))  {
2018
0
          *as = peer->as;
2019
0
          return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT;
2020
0
        }
2021
0
      }
2022
0
    }
2023
2024
    /* Existing peer's AS number change. */
2025
0
    if (((peer->as_type == AS_SPECIFIED) && peer->as != *as)
2026
0
        || (peer->as_type != as_type))
2027
0
      peer_as_change(peer, *as, as_type, as_str);
2028
0
  } else {
2029
0
    if (conf_if)
2030
0
      return BGP_ERR_NO_INTERFACE_CONFIG;
2031
2032
    /* If the peer is not part of our confederation, and its not an
2033
       iBGP peer then spoof the source AS */
2034
0
    if (bgp_config_check(bgp, BGP_CONFIG_CONFEDERATION) &&
2035
0
        !bgp_confederation_peers_check(bgp, *as) && *as &&
2036
0
        bgp->as != *as)
2037
0
      local_as = bgp->confed_id;
2038
0
    else
2039
0
      local_as = bgp->as;
2040
2041
0
    peer_create(su, conf_if, bgp, local_as, *as, as_type, NULL,
2042
0
          true, as_str);
2043
0
  }
2044
2045
0
  return 0;
2046
0
}
2047
2048
const char *bgp_get_name_by_role(uint8_t role)
2049
0
{
2050
0
  switch (role) {
2051
0
  case ROLE_PROVIDER:
2052
0
    return "provider";
2053
0
  case ROLE_RS_SERVER:
2054
0
    return "rs-server";
2055
0
  case ROLE_RS_CLIENT:
2056
0
    return "rs-client";
2057
0
  case ROLE_CUSTOMER:
2058
0
    return "customer";
2059
0
  case ROLE_PEER:
2060
0
    return "peer";
2061
0
  case ROLE_UNDEFINED:
2062
0
    return "undefined";
2063
0
  }
2064
0
  return "unknown";
2065
0
}
2066
2067
enum asnotation_mode bgp_get_asnotation(struct bgp *bgp)
2068
153
{
2069
153
  if (!bgp)
2070
0
    return ASNOTATION_PLAIN;
2071
153
  return bgp->asnotation;
2072
153
}
2073
2074
static void peer_group2peer_config_copy_af(struct peer_group *group,
2075
             struct peer *peer, afi_t afi,
2076
             safi_t safi)
2077
0
{
2078
0
  int in = FILTER_IN;
2079
0
  int out = FILTER_OUT;
2080
0
  uint64_t flags_tmp;
2081
0
  uint64_t pflags_ovrd;
2082
0
  uint8_t *pfilter_ovrd;
2083
0
  struct peer *conf;
2084
2085
0
  conf = group->conf;
2086
0
  pflags_ovrd = peer->af_flags_override[afi][safi];
2087
0
  pfilter_ovrd = &peer->filter_override[afi][safi][in];
2088
2089
  /* peer af_flags apply */
2090
0
  flags_tmp = conf->af_flags[afi][safi] & ~pflags_ovrd;
2091
0
  flags_tmp ^= conf->af_flags_invert[afi][safi]
2092
0
         ^ peer->af_flags_invert[afi][safi];
2093
0
  flags_tmp &= ~pflags_ovrd;
2094
2095
0
  UNSET_FLAG(peer->af_flags[afi][safi], ~pflags_ovrd);
2096
0
  SET_FLAG(peer->af_flags[afi][safi], flags_tmp);
2097
0
  SET_FLAG(peer->af_flags_invert[afi][safi],
2098
0
     conf->af_flags_invert[afi][safi]);
2099
2100
  /* maximum-prefix */
2101
0
  if (!CHECK_FLAG(pflags_ovrd, PEER_FLAG_MAX_PREFIX)) {
2102
0
    PEER_ATTR_INHERIT(peer, group, pmax[afi][safi]);
2103
0
    PEER_ATTR_INHERIT(peer, group, pmax_threshold[afi][safi]);
2104
0
    PEER_ATTR_INHERIT(peer, group, pmax_restart[afi][safi]);
2105
0
  }
2106
2107
  /* maximum-prefix-out */
2108
0
  if (!CHECK_FLAG(pflags_ovrd, PEER_FLAG_MAX_PREFIX_OUT))
2109
0
    PEER_ATTR_INHERIT(peer, group, pmax_out[afi][safi]);
2110
2111
  /* allowas-in */
2112
0
  if (!CHECK_FLAG(pflags_ovrd, PEER_FLAG_ALLOWAS_IN))
2113
0
    PEER_ATTR_INHERIT(peer, group, allowas_in[afi][safi]);
2114
2115
  /* soo */
2116
0
  if (!CHECK_FLAG(pflags_ovrd, PEER_FLAG_SOO))
2117
0
    PEER_ATTR_INHERIT(peer, group, soo[afi][safi]);
2118
2119
  /* weight */
2120
0
  if (!CHECK_FLAG(pflags_ovrd, PEER_FLAG_WEIGHT))
2121
0
    PEER_ATTR_INHERIT(peer, group, weight[afi][safi]);
2122
2123
  /* default-originate route-map */
2124
0
  if (!CHECK_FLAG(pflags_ovrd, PEER_FLAG_DEFAULT_ORIGINATE)) {
2125
0
    PEER_STR_ATTR_INHERIT(peer, group, default_rmap[afi][safi].name,
2126
0
              MTYPE_ROUTE_MAP_NAME);
2127
0
    PEER_ATTR_INHERIT(peer, group, default_rmap[afi][safi].map);
2128
0
  }
2129
2130
  /* inbound filter apply */
2131
0
  if (!CHECK_FLAG(pfilter_ovrd[in], PEER_FT_DISTRIBUTE_LIST)) {
2132
0
    PEER_STR_ATTR_INHERIT(peer, group,
2133
0
              filter[afi][safi].dlist[in].name,
2134
0
              MTYPE_BGP_FILTER_NAME);
2135
0
    PEER_ATTR_INHERIT(peer, group,
2136
0
          filter[afi][safi].dlist[in].alist);
2137
0
  }
2138
2139
0
  if (!CHECK_FLAG(pfilter_ovrd[in], PEER_FT_PREFIX_LIST)) {
2140
0
    PEER_STR_ATTR_INHERIT(peer, group,
2141
0
              filter[afi][safi].plist[in].name,
2142
0
              MTYPE_BGP_FILTER_NAME);
2143
0
    PEER_ATTR_INHERIT(peer, group,
2144
0
          filter[afi][safi].plist[in].plist);
2145
0
  }
2146
2147
0
  if (!CHECK_FLAG(pfilter_ovrd[in], PEER_FT_FILTER_LIST)) {
2148
0
    PEER_STR_ATTR_INHERIT(peer, group,
2149
0
              filter[afi][safi].aslist[in].name,
2150
0
              MTYPE_BGP_FILTER_NAME);
2151
0
    PEER_ATTR_INHERIT(peer, group,
2152
0
          filter[afi][safi].aslist[in].aslist);
2153
0
  }
2154
2155
0
  if (!CHECK_FLAG(pfilter_ovrd[RMAP_IN], PEER_FT_ROUTE_MAP)) {
2156
0
    PEER_STR_ATTR_INHERIT(peer, group,
2157
0
              filter[afi][safi].map[in].name,
2158
0
              MTYPE_BGP_FILTER_NAME);
2159
0
    PEER_ATTR_INHERIT(peer, group,
2160
0
          filter[afi][safi].map[RMAP_IN].map);
2161
0
  }
2162
2163
  /* outbound filter apply */
2164
0
  if (!CHECK_FLAG(pfilter_ovrd[out], PEER_FT_DISTRIBUTE_LIST)) {
2165
0
    PEER_STR_ATTR_INHERIT(peer, group,
2166
0
              filter[afi][safi].dlist[out].name,
2167
0
              MTYPE_BGP_FILTER_NAME);
2168
0
    PEER_ATTR_INHERIT(peer, group,
2169
0
          filter[afi][safi].dlist[out].alist);
2170
0
  }
2171
2172
0
  if (!CHECK_FLAG(pfilter_ovrd[out], PEER_FT_PREFIX_LIST)) {
2173
0
    PEER_STR_ATTR_INHERIT(peer, group,
2174
0
              filter[afi][safi].plist[out].name,
2175
0
              MTYPE_BGP_FILTER_NAME);
2176
0
    PEER_ATTR_INHERIT(peer, group,
2177
0
          filter[afi][safi].plist[out].plist);
2178
0
  }
2179
2180
0
  if (!CHECK_FLAG(pfilter_ovrd[out], PEER_FT_FILTER_LIST)) {
2181
0
    PEER_STR_ATTR_INHERIT(peer, group,
2182
0
              filter[afi][safi].aslist[out].name,
2183
0
              MTYPE_BGP_FILTER_NAME);
2184
0
    PEER_ATTR_INHERIT(peer, group,
2185
0
          filter[afi][safi].aslist[out].aslist);
2186
0
  }
2187
2188
0
  if (!CHECK_FLAG(pfilter_ovrd[RMAP_OUT], PEER_FT_ROUTE_MAP)) {
2189
0
    PEER_STR_ATTR_INHERIT(peer, group,
2190
0
              filter[afi][safi].map[RMAP_OUT].name,
2191
0
              MTYPE_BGP_FILTER_NAME);
2192
0
    PEER_ATTR_INHERIT(peer, group,
2193
0
          filter[afi][safi].map[RMAP_OUT].map);
2194
0
  }
2195
2196
  /* nondirectional filter apply */
2197
0
  if (!CHECK_FLAG(pfilter_ovrd[0], PEER_FT_UNSUPPRESS_MAP)) {
2198
0
    PEER_STR_ATTR_INHERIT(peer, group, filter[afi][safi].usmap.name,
2199
0
              MTYPE_BGP_FILTER_NAME);
2200
0
    PEER_ATTR_INHERIT(peer, group, filter[afi][safi].usmap.map);
2201
0
  }
2202
2203
  /* Conditional Advertisements */
2204
0
  if (!CHECK_FLAG(pfilter_ovrd[RMAP_OUT], PEER_FT_ADVERTISE_MAP)) {
2205
0
    PEER_STR_ATTR_INHERIT(peer, group,
2206
0
              filter[afi][safi].advmap.aname,
2207
0
              MTYPE_BGP_FILTER_NAME);
2208
0
    PEER_ATTR_INHERIT(peer, group, filter[afi][safi].advmap.amap);
2209
0
    PEER_STR_ATTR_INHERIT(peer, group,
2210
0
              filter[afi][safi].advmap.cname,
2211
0
              MTYPE_BGP_FILTER_NAME);
2212
0
    PEER_ATTR_INHERIT(peer, group, filter[afi][safi].advmap.cmap);
2213
0
    PEER_ATTR_INHERIT(peer, group,
2214
0
          filter[afi][safi].advmap.condition);
2215
0
  }
2216
2217
0
  if (peer->addpath_type[afi][safi] == BGP_ADDPATH_NONE) {
2218
0
    peer->addpath_type[afi][safi] = conf->addpath_type[afi][safi];
2219
0
    bgp_addpath_type_changed(conf->bgp);
2220
0
  }
2221
0
}
2222
2223
static int peer_activate_af(struct peer *peer, afi_t afi, safi_t safi)
2224
2
{
2225
2
  int active;
2226
2
  struct peer *other;
2227
2228
2
  if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
2229
0
    flog_err(EC_BGP_PEER_GROUP, "%s was called for peer-group %s",
2230
0
       __func__, peer->host);
2231
0
    return 1;
2232
0
  }
2233
2234
  /* Do not activate a peer for both SAFI_UNICAST and SAFI_LABELED_UNICAST
2235
   */
2236
2
  if ((safi == SAFI_UNICAST && peer->afc[afi][SAFI_LABELED_UNICAST])
2237
2
      || (safi == SAFI_LABELED_UNICAST && peer->afc[afi][SAFI_UNICAST]))
2238
0
    return BGP_ERR_PEER_SAFI_CONFLICT;
2239
2240
  /* Nothing to do if we've already activated this peer */
2241
2
  if (peer->afc[afi][safi])
2242
0
    return 0;
2243
2244
2
  if (peer_af_create(peer, afi, safi) == NULL)
2245
0
    return 1;
2246
2247
2
  active = peer_active(peer);
2248
2
  peer->afc[afi][safi] = 1;
2249
2250
2
  if (peer->group)
2251
0
    peer_group2peer_config_copy_af(peer->group, peer, afi, safi);
2252
2253
2
  if (!active && peer_active(peer)) {
2254
0
    bgp_timer_set(peer);
2255
2
  } else {
2256
2
    if (peer_established(peer)) {
2257
2
      if (CHECK_FLAG(peer->cap, PEER_CAP_DYNAMIC_RCV)) {
2258
2
        peer->afc_adv[afi][safi] = 1;
2259
2
        bgp_capability_send(peer, afi, safi,
2260
2
                CAPABILITY_CODE_MP,
2261
2
                CAPABILITY_ACTION_SET);
2262
2
        if (peer->afc_recv[afi][safi]) {
2263
0
          peer->afc_nego[afi][safi] = 1;
2264
0
          bgp_announce_route(peer, afi, safi,
2265
0
                 false);
2266
0
        }
2267
2
      } else {
2268
0
        peer->last_reset = PEER_DOWN_AF_ACTIVATE;
2269
0
        bgp_notify_send(peer, BGP_NOTIFY_CEASE,
2270
0
            BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2271
0
      }
2272
2
    }
2273
2
    if (peer->status == OpenSent || peer->status == OpenConfirm) {
2274
0
      peer->last_reset = PEER_DOWN_AF_ACTIVATE;
2275
0
      bgp_notify_send(peer, BGP_NOTIFY_CEASE,
2276
0
          BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2277
0
    }
2278
    /*
2279
     * If we are turning on a AFI/SAFI locally and we've
2280
     * started bringing a peer up, we need to tell
2281
     * the other peer to restart because we might loose
2282
     * configuration here because when the doppelganger
2283
     * gets to a established state due to how
2284
     * we resolve we could just overwrite the afi/safi
2285
     * activation.
2286
     */
2287
2
    other = peer->doppelganger;
2288
2
    if (other
2289
2
        && (other->status == OpenSent
2290
0
      || other->status == OpenConfirm)) {
2291
0
      other->last_reset = PEER_DOWN_AF_ACTIVATE;
2292
0
      bgp_notify_send(other, BGP_NOTIFY_CEASE,
2293
0
          BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2294
0
    }
2295
2
  }
2296
2297
2
  return 0;
2298
2
}
2299
2300
/* Activate the peer or peer group for specified AFI and SAFI.  */
2301
int peer_activate(struct peer *peer, afi_t afi, safi_t safi)
2302
2
{
2303
2
  int ret = 0;
2304
2
  struct peer_group *group;
2305
2
  struct listnode *node, *nnode;
2306
2
  struct peer *tmp_peer;
2307
2
  struct bgp *bgp;
2308
2309
  /* Nothing to do if we've already activated this peer */
2310
2
  if (peer->afc[afi][safi])
2311
0
    return ret;
2312
2313
2
  bgp = peer->bgp;
2314
2315
  /* This is a peer-group so activate all of the members of the
2316
   * peer-group as well */
2317
2
  if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
2318
2319
    /* Do not activate a peer for both SAFI_UNICAST and
2320
     * SAFI_LABELED_UNICAST */
2321
0
    if ((safi == SAFI_UNICAST
2322
0
         && peer->afc[afi][SAFI_LABELED_UNICAST])
2323
0
        || (safi == SAFI_LABELED_UNICAST
2324
0
      && peer->afc[afi][SAFI_UNICAST]))
2325
0
      return BGP_ERR_PEER_SAFI_CONFLICT;
2326
2327
0
    peer->afc[afi][safi] = 1;
2328
0
    group = peer->group;
2329
2330
0
    for (ALL_LIST_ELEMENTS(group->peer, node, nnode, tmp_peer)) {
2331
0
      ret |= peer_activate_af(tmp_peer, afi, safi);
2332
0
    }
2333
2
  } else {
2334
2
    ret |= peer_activate_af(peer, afi, safi);
2335
2
  }
2336
2337
  /* If this is the first peer to be activated for this
2338
   * afi/labeled-unicast recalc bestpaths to trigger label allocation */
2339
2
  if (ret != BGP_ERR_PEER_SAFI_CONFLICT && safi == SAFI_LABELED_UNICAST
2340
2
      && !bgp->allocate_mpls_labels[afi][SAFI_UNICAST]) {
2341
2342
0
    if (BGP_DEBUG(zebra, ZEBRA))
2343
0
      zlog_debug(
2344
0
        "peer(s) are now active for labeled-unicast, allocate MPLS labels");
2345
2346
0
    bgp->allocate_mpls_labels[afi][SAFI_UNICAST] = 1;
2347
0
    bgp_recalculate_afi_safi_bestpaths(bgp, afi, SAFI_UNICAST);
2348
0
  }
2349
2350
2
  if (safi == SAFI_FLOWSPEC) {
2351
    /* connect to table manager */
2352
0
    bgp_zebra_init_tm_connect(bgp);
2353
0
  }
2354
2
  return ret;
2355
2
}
2356
2357
static bool non_peergroup_deactivate_af(struct peer *peer, afi_t afi,
2358
          safi_t safi)
2359
0
{
2360
0
  if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
2361
0
    flog_err(EC_BGP_PEER_GROUP, "%s was called for peer-group %s",
2362
0
       __func__, peer->host);
2363
0
    return true;
2364
0
  }
2365
2366
  /* Nothing to do if we've already deactivated this peer */
2367
0
  if (!peer->afc[afi][safi])
2368
0
    return false;
2369
2370
  /* De-activate the address family configuration. */
2371
0
  peer->afc[afi][safi] = 0;
2372
2373
0
  if (peer_af_delete(peer, afi, safi) != 0) {
2374
0
    flog_err(EC_BGP_PEER_DELETE,
2375
0
       "couldn't delete af structure for peer %s(%s, %s)",
2376
0
       peer->host, afi2str(afi), safi2str(safi));
2377
0
    return true;
2378
0
  }
2379
2380
0
  if (peer_established(peer)) {
2381
0
    if (CHECK_FLAG(peer->cap, PEER_CAP_DYNAMIC_RCV)) {
2382
0
      peer->afc_adv[afi][safi] = 0;
2383
0
      peer->afc_nego[afi][safi] = 0;
2384
2385
0
      if (peer_active_nego(peer)) {
2386
0
        bgp_capability_send(peer, afi, safi,
2387
0
                CAPABILITY_CODE_MP,
2388
0
                CAPABILITY_ACTION_UNSET);
2389
0
        bgp_clear_route(peer, afi, safi);
2390
0
        peer->pcount[afi][safi] = 0;
2391
0
      } else {
2392
0
        peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE;
2393
0
        bgp_notify_send(peer, BGP_NOTIFY_CEASE,
2394
0
            BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2395
0
      }
2396
0
    } else {
2397
0
      peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE;
2398
0
      bgp_notify_send(peer, BGP_NOTIFY_CEASE,
2399
0
          BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2400
0
    }
2401
0
  }
2402
2403
0
  return false;
2404
0
}
2405
2406
int peer_deactivate(struct peer *peer, afi_t afi, safi_t safi)
2407
0
{
2408
0
  int ret = 0;
2409
0
  struct peer_group *group;
2410
0
  struct peer *tmp_peer;
2411
0
  struct listnode *node, *nnode;
2412
0
  struct bgp *bgp;
2413
2414
  /* Nothing to do if we've already de-activated this peer */
2415
0
  if (!peer->afc[afi][safi])
2416
0
    return ret;
2417
2418
  /* This is a peer-group so de-activate all of the members of the
2419
   * peer-group as well */
2420
0
  if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
2421
0
    peer->afc[afi][safi] = 0;
2422
0
    group = peer->group;
2423
2424
0
    for (ALL_LIST_ELEMENTS(group->peer, node, nnode, tmp_peer)) {
2425
0
      ret |= non_peergroup_deactivate_af(tmp_peer, afi, safi);
2426
0
    }
2427
0
  } else {
2428
0
    ret |= non_peergroup_deactivate_af(peer, afi, safi);
2429
0
  }
2430
2431
0
  bgp = peer->bgp;
2432
2433
  /* If this is the last peer to be deactivated for this
2434
   * afi/labeled-unicast recalc bestpaths to trigger label deallocation */
2435
0
  if (safi == SAFI_LABELED_UNICAST
2436
0
      && bgp->allocate_mpls_labels[afi][SAFI_UNICAST]
2437
0
      && !bgp_afi_safi_peer_exists(bgp, afi, safi)) {
2438
2439
0
    if (BGP_DEBUG(zebra, ZEBRA))
2440
0
      zlog_debug(
2441
0
        "peer(s) are no longer active for labeled-unicast, deallocate MPLS labels");
2442
2443
0
    bgp->allocate_mpls_labels[afi][SAFI_UNICAST] = 0;
2444
0
    bgp_recalculate_afi_safi_bestpaths(bgp, afi, SAFI_UNICAST);
2445
0
  }
2446
0
  return ret;
2447
0
}
2448
2449
void peer_nsf_stop(struct peer *peer)
2450
0
{
2451
0
  afi_t afi;
2452
0
  safi_t safi;
2453
2454
0
  UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT);
2455
0
  UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE);
2456
2457
0
  FOREACH_AFI_SAFI_NSF (afi, safi) {
2458
0
    peer->nsf[afi][safi] = 0;
2459
0
    EVENT_OFF(peer->t_llgr_stale[afi][safi]);
2460
0
  }
2461
2462
0
  if (peer->t_gr_restart) {
2463
0
    EVENT_OFF(peer->t_gr_restart);
2464
0
    if (bgp_debug_neighbor_events(peer))
2465
0
      zlog_debug("%pBP graceful restart timer stopped", peer);
2466
0
  }
2467
0
  if (peer->t_gr_stale) {
2468
0
    EVENT_OFF(peer->t_gr_stale);
2469
0
    if (bgp_debug_neighbor_events(peer))
2470
0
      zlog_debug(
2471
0
        "%pBP graceful restart stalepath timer stopped",
2472
0
        peer);
2473
0
  }
2474
0
  bgp_clear_route_all(peer);
2475
0
}
2476
2477
/* Delete peer from confguration.
2478
 *
2479
 * The peer is moved to a dead-end "Deleted" neighbour-state, to allow
2480
 * it to "cool off" and refcounts to hit 0, at which state it is freed.
2481
 *
2482
 * This function /should/ take care to be idempotent, to guard against
2483
 * it being called multiple times through stray events that come in
2484
 * that happen to result in this function being called again.  That
2485
 * said, getting here for a "Deleted" peer is a bug in the neighbour
2486
 * FSM.
2487
 */
2488
int peer_delete(struct peer *peer)
2489
0
{
2490
0
  int i;
2491
0
  afi_t afi;
2492
0
  safi_t safi;
2493
0
  struct bgp *bgp;
2494
0
  struct bgp_filter *filter;
2495
0
  struct listnode *pn;
2496
0
  int accept_peer;
2497
2498
0
  assert(peer->status != Deleted);
2499
2500
0
  bgp = peer->bgp;
2501
0
  accept_peer = CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER);
2502
2503
0
  bgp_soft_reconfig_table_task_cancel(bgp, NULL, peer);
2504
2505
0
  bgp_keepalives_off(peer);
2506
0
  bgp_reads_off(peer);
2507
0
  bgp_writes_off(peer);
2508
0
  event_cancel_event_ready(bm->master, peer);
2509
0
  FOREACH_AFI_SAFI (afi, safi)
2510
0
    EVENT_OFF(peer->t_revalidate_all[afi][safi]);
2511
0
  assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_WRITES_ON));
2512
0
  assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_READS_ON));
2513
0
  assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_KEEPALIVES_ON));
2514
2515
0
  if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT))
2516
0
    peer_nsf_stop(peer);
2517
2518
0
  SET_FLAG(peer->flags, PEER_FLAG_DELETE);
2519
2520
  /* Remove BFD settings. */
2521
0
  if (peer->bfd_config)
2522
0
    bgp_peer_remove_bfd_config(peer);
2523
2524
  /* If this peer belongs to peer group, clear up the
2525
     relationship.  */
2526
0
  if (peer->group) {
2527
0
    if (peer_dynamic_neighbor(peer))
2528
0
      peer_drop_dynamic_neighbor(peer);
2529
2530
0
    if ((pn = listnode_lookup(peer->group->peer, peer))) {
2531
0
      peer = peer_unlock(
2532
0
        peer); /* group->peer list reference */
2533
0
      list_delete_node(peer->group->peer, pn);
2534
0
    }
2535
0
    peer->group = NULL;
2536
0
  }
2537
2538
  /* Withdraw all information from routing table.  We can not use
2539
   * BGP_EVENT_ADD (peer, BGP_Stop) at here.  Because the event is
2540
   * executed after peer structure is deleted.
2541
   */
2542
0
  peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE;
2543
0
  bgp_stop(peer);
2544
0
  UNSET_FLAG(peer->flags, PEER_FLAG_DELETE);
2545
2546
0
  if (peer->doppelganger) {
2547
0
    peer->doppelganger->doppelganger = NULL;
2548
0
    peer->doppelganger = NULL;
2549
0
  }
2550
2551
0
  UNSET_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER);
2552
0
  bgp_fsm_change_status(peer, Deleted);
2553
2554
  /* Remove from NHT */
2555
0
  if (CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
2556
0
    bgp_unlink_nexthop_by_peer(peer);
2557
2558
  /* Password configuration */
2559
0
  if (CHECK_FLAG(peer->flags, PEER_FLAG_PASSWORD)) {
2560
0
    XFREE(MTYPE_PEER_PASSWORD, peer->password);
2561
0
    if (!accept_peer && !BGP_PEER_SU_UNSPEC(peer)
2562
0
        && !CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)
2563
0
        && !CHECK_FLAG(peer->flags, PEER_FLAG_DYNAMIC_NEIGHBOR))
2564
0
      bgp_md5_unset(peer);
2565
0
  }
2566
2567
0
  bgp_timer_set(peer); /* stops all timers for Deleted */
2568
2569
  /* Delete from all peer list. */
2570
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)
2571
0
      && (pn = listnode_lookup(bgp->peer, peer))) {
2572
    /*
2573
     * Removing from the list node first because
2574
     * peer_unlock *can* call peer_delete( I know,
2575
     * I know ).  So let's remove it and in
2576
     * the su recalculate function we'll ensure
2577
     * it's in there or not.
2578
     */
2579
0
    list_delete_node(bgp->peer, pn);
2580
0
    hash_release(bgp->peerhash, peer);
2581
0
    peer_unlock(peer); /* bgp peer list reference */
2582
0
  }
2583
2584
  /* Buffers.  */
2585
0
  if (peer->ibuf) {
2586
0
    stream_fifo_free(peer->ibuf);
2587
0
    peer->ibuf = NULL;
2588
0
  }
2589
2590
0
  if (peer->obuf) {
2591
0
    stream_fifo_free(peer->obuf);
2592
0
    peer->obuf = NULL;
2593
0
  }
2594
2595
0
  if (peer->ibuf_work) {
2596
0
    ringbuf_del(peer->ibuf_work);
2597
0
    peer->ibuf_work = NULL;
2598
0
  }
2599
2600
  /* Local and remote addresses. */
2601
0
  if (peer->su_local) {
2602
0
    sockunion_free(peer->su_local);
2603
0
    peer->su_local = NULL;
2604
0
  }
2605
2606
0
  if (peer->su_remote) {
2607
0
    sockunion_free(peer->su_remote);
2608
0
    peer->su_remote = NULL;
2609
0
  }
2610
2611
  /* Free filter related memory.  */
2612
0
  FOREACH_AFI_SAFI (afi, safi) {
2613
0
    filter = &peer->filter[afi][safi];
2614
2615
0
    for (i = FILTER_IN; i < FILTER_MAX; i++) {
2616
0
      XFREE(MTYPE_BGP_FILTER_NAME, filter->dlist[i].name);
2617
0
      XFREE(MTYPE_BGP_FILTER_NAME, filter->plist[i].name);
2618
0
      XFREE(MTYPE_BGP_FILTER_NAME, filter->aslist[i].name);
2619
0
    }
2620
2621
0
    for (i = RMAP_IN; i < RMAP_MAX; i++) {
2622
0
      XFREE(MTYPE_BGP_FILTER_NAME, filter->map[i].name);
2623
0
    }
2624
2625
0
    XFREE(MTYPE_BGP_FILTER_NAME, filter->usmap.name);
2626
0
    XFREE(MTYPE_ROUTE_MAP_NAME, peer->default_rmap[afi][safi].name);
2627
0
    ecommunity_free(&peer->soo[afi][safi]);
2628
0
  }
2629
2630
0
  FOREACH_AFI_SAFI (afi, safi)
2631
0
    peer_af_delete(peer, afi, safi);
2632
2633
0
  XFREE(MTYPE_BGP_PEER_HOST, peer->hostname);
2634
0
  XFREE(MTYPE_BGP_PEER_HOST, peer->domainname);
2635
0
  XFREE(MTYPE_BGP_SOFT_VERSION, peer->soft_version);
2636
2637
0
  peer_unlock(peer); /* initial reference */
2638
2639
0
  return 0;
2640
0
}
2641
2642
static int peer_group_cmp(struct peer_group *g1, struct peer_group *g2)
2643
0
{
2644
0
  return strcmp(g1->name, g2->name);
2645
0
}
2646
2647
/* Peer group cofiguration. */
2648
static struct peer_group *peer_group_new(void)
2649
0
{
2650
0
  return XCALLOC(MTYPE_PEER_GROUP, sizeof(struct peer_group));
2651
0
}
2652
2653
static void peer_group_free(struct peer_group *group)
2654
0
{
2655
0
  XFREE(MTYPE_PEER_GROUP, group);
2656
0
}
2657
2658
struct peer_group *peer_group_lookup(struct bgp *bgp, const char *name)
2659
0
{
2660
0
  struct peer_group *group;
2661
0
  struct listnode *node, *nnode;
2662
2663
0
  for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) {
2664
0
    if (strcmp(group->name, name) == 0)
2665
0
      return group;
2666
0
  }
2667
0
  return NULL;
2668
0
}
2669
2670
struct peer_group *peer_group_get(struct bgp *bgp, const char *name)
2671
0
{
2672
0
  struct peer_group *group;
2673
0
  afi_t afi;
2674
0
  safi_t safi;
2675
2676
0
  group = peer_group_lookup(bgp, name);
2677
0
  if (group)
2678
0
    return group;
2679
2680
0
  group = peer_group_new();
2681
0
  group->bgp = bgp;
2682
0
  XFREE(MTYPE_PEER_GROUP_HOST, group->name);
2683
0
  group->name = XSTRDUP(MTYPE_PEER_GROUP_HOST, name);
2684
0
  group->peer = list_new();
2685
0
  for (afi = AFI_IP; afi < AFI_MAX; afi++)
2686
0
    group->listen_range[afi] = list_new();
2687
0
  group->conf = peer_new(bgp);
2688
0
  FOREACH_AFI_SAFI (afi, safi) {
2689
0
    if (bgp->default_af[afi][safi])
2690
0
      group->conf->afc[afi][safi] = 1;
2691
0
  }
2692
0
  XFREE(MTYPE_BGP_PEER_HOST, group->conf->host);
2693
0
  group->conf->host = XSTRDUP(MTYPE_BGP_PEER_HOST, name);
2694
0
  group->conf->group = group;
2695
0
  group->conf->as = 0;
2696
0
  group->conf->ttl = BGP_DEFAULT_TTL;
2697
0
  group->conf->gtsm_hops = BGP_GTSM_HOPS_DISABLED;
2698
0
  group->conf->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
2699
0
  SET_FLAG(group->conf->sflags, PEER_STATUS_GROUP);
2700
0
  listnode_add_sort(bgp->group, group);
2701
2702
0
  return group;
2703
0
}
2704
2705
static void peer_group2peer_config_copy(struct peer_group *group,
2706
          struct peer *peer)
2707
0
{
2708
0
  uint64_t flags_tmp;
2709
0
  struct peer *conf;
2710
0
  bool config_node = !!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE);
2711
2712
0
  conf = group->conf;
2713
2714
  /* remote-as */
2715
0
  if (conf->as)
2716
0
    peer->as = conf->as;
2717
2718
  /* local-as */
2719
0
  if (!CHECK_FLAG(peer->flags_override, PEER_FLAG_LOCAL_AS))
2720
0
    peer->change_local_as = conf->change_local_as;
2721
2722
  /* If peer-group has configured TTL then override it */
2723
0
  if (conf->ttl != BGP_DEFAULT_TTL)
2724
0
    peer->ttl = conf->ttl;
2725
2726
  /* GTSM hops */
2727
0
  peer->gtsm_hops = conf->gtsm_hops;
2728
2729
  /* peer flags apply */
2730
0
  flags_tmp = conf->flags & ~peer->flags_override;
2731
0
  flags_tmp ^= conf->flags_invert ^ peer->flags_invert;
2732
0
  flags_tmp &= ~peer->flags_override;
2733
2734
0
  UNSET_FLAG(peer->flags, ~peer->flags_override);
2735
0
  SET_FLAG(peer->flags, flags_tmp);
2736
0
  SET_FLAG(peer->flags_invert, conf->flags_invert);
2737
2738
0
  if (config_node)
2739
0
    SET_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE);
2740
2741
  /* peer timers apply */
2742
0
  if (!CHECK_FLAG(peer->flags_override, PEER_FLAG_TIMER)) {
2743
0
    PEER_ATTR_INHERIT(peer, group, holdtime);
2744
0
    PEER_ATTR_INHERIT(peer, group, keepalive);
2745
0
  }
2746
2747
0
  if (!CHECK_FLAG(peer->flags_override, PEER_FLAG_TIMER_CONNECT)) {
2748
0
    PEER_ATTR_INHERIT(peer, group, connect);
2749
0
    if (CHECK_FLAG(conf->flags, PEER_FLAG_TIMER_CONNECT))
2750
0
      peer->v_connect = conf->connect;
2751
0
    else
2752
0
      peer->v_connect = peer->bgp->default_connect_retry;
2753
0
  }
2754
2755
0
  if (!CHECK_FLAG(peer->flags_override, PEER_FLAG_TIMER_DELAYOPEN)) {
2756
0
    PEER_ATTR_INHERIT(peer, group, delayopen);
2757
0
    if (CHECK_FLAG(conf->flags, PEER_FLAG_TIMER_DELAYOPEN))
2758
0
      peer->v_delayopen = conf->delayopen;
2759
0
    else
2760
0
      peer->v_delayopen = peer->bgp->default_delayopen;
2761
0
  }
2762
2763
  /* advertisement-interval apply */
2764
0
  if (!CHECK_FLAG(peer->flags_override, PEER_FLAG_ROUTEADV)) {
2765
0
    PEER_ATTR_INHERIT(peer, group, routeadv);
2766
0
    if (CHECK_FLAG(conf->flags, PEER_FLAG_ROUTEADV))
2767
0
      peer->v_routeadv = conf->routeadv;
2768
0
    else
2769
0
      peer->v_routeadv = (peer_sort(peer) == BGP_PEER_IBGP)
2770
0
               ? BGP_DEFAULT_IBGP_ROUTEADV
2771
0
               : BGP_DEFAULT_EBGP_ROUTEADV;
2772
0
  }
2773
2774
  /* capability extended-nexthop apply */
2775
0
  if (!CHECK_FLAG(peer->flags_override, PEER_FLAG_CAPABILITY_ENHE))
2776
0
    if (CHECK_FLAG(conf->flags, PEER_FLAG_CAPABILITY_ENHE))
2777
0
      SET_FLAG(peer->flags, PEER_FLAG_CAPABILITY_ENHE);
2778
2779
  /* capability software-version apply */
2780
0
  if (!CHECK_FLAG(peer->flags_override,
2781
0
      PEER_FLAG_CAPABILITY_SOFT_VERSION))
2782
0
    if (CHECK_FLAG(conf->flags, PEER_FLAG_CAPABILITY_SOFT_VERSION))
2783
0
      SET_FLAG(peer->flags,
2784
0
         PEER_FLAG_CAPABILITY_SOFT_VERSION);
2785
2786
  /* password apply */
2787
0
  if (!CHECK_FLAG(peer->flags_override, PEER_FLAG_PASSWORD))
2788
0
    PEER_STR_ATTR_INHERIT(peer, group, password,
2789
0
              MTYPE_PEER_PASSWORD);
2790
2791
0
  if (!BGP_PEER_SU_UNSPEC(peer))
2792
0
    bgp_md5_set(peer);
2793
2794
  /* update-source apply */
2795
0
  if (!CHECK_FLAG(peer->flags_override, PEER_FLAG_UPDATE_SOURCE)) {
2796
0
    if (conf->update_source) {
2797
0
      XFREE(MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
2798
0
      PEER_SU_ATTR_INHERIT(peer, group, update_source);
2799
0
    } else if (conf->update_if) {
2800
0
      sockunion_free(peer->update_source);
2801
0
      PEER_STR_ATTR_INHERIT(peer, group, update_if,
2802
0
                MTYPE_PEER_UPDATE_SOURCE);
2803
0
    }
2804
0
  }
2805
2806
  /* role */
2807
0
  PEER_ATTR_INHERIT(peer, group, local_role);
2808
2809
  /* Update GR flags for the peer. */
2810
0
  bgp_peer_gr_flags_update(peer);
2811
2812
  /* Apply BFD settings from group to peer if it exists. */
2813
0
  if (conf->bfd_config) {
2814
0
    bgp_peer_configure_bfd(peer, false);
2815
0
    bgp_peer_config_apply(peer, group);
2816
0
  }
2817
0
}
2818
2819
/* Peer group's remote AS configuration.  */
2820
int peer_group_remote_as(struct bgp *bgp, const char *group_name, as_t *as,
2821
       int as_type, const char *as_str)
2822
0
{
2823
0
  struct peer_group *group;
2824
0
  struct peer *peer;
2825
0
  struct listnode *node, *nnode;
2826
2827
0
  group = peer_group_lookup(bgp, group_name);
2828
0
  if (!group)
2829
0
    return -1;
2830
2831
0
  if ((as_type == group->conf->as_type) && (group->conf->as == *as))
2832
0
    return 0;
2833
2834
2835
  /* When we setup peer-group AS number all peer group member's AS
2836
     number must be updated to same number.  */
2837
0
  peer_as_change(group->conf, *as, as_type, as_str);
2838
2839
0
  for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
2840
0
    if (((peer->as_type == AS_SPECIFIED) && peer->as != *as)
2841
0
        || (peer->as_type != as_type))
2842
0
      peer_as_change(peer, *as, as_type, as_str);
2843
0
  }
2844
2845
0
  return 0;
2846
0
}
2847
2848
void peer_notify_unconfig(struct peer *peer)
2849
0
{
2850
0
  if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
2851
0
    bgp_notify_send(peer, BGP_NOTIFY_CEASE,
2852
0
        BGP_NOTIFY_CEASE_PEER_UNCONFIG);
2853
0
}
2854
2855
static void peer_notify_shutdown(struct peer *peer)
2856
0
{
2857
0
  if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)) {
2858
0
    if (bgp_debug_neighbor_events(peer))
2859
0
      zlog_debug(
2860
0
        "%pBP configured Graceful-Restart, skipping shutdown notification",
2861
0
        peer);
2862
0
    return;
2863
0
  }
2864
2865
0
  if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
2866
0
    bgp_notify_send(peer, BGP_NOTIFY_CEASE,
2867
0
        BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
2868
0
}
2869
2870
void peer_group_notify_unconfig(struct peer_group *group)
2871
0
{
2872
0
  struct peer *peer, *other;
2873
0
  struct listnode *node, *nnode;
2874
2875
0
  for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
2876
0
    other = peer->doppelganger;
2877
0
    if (other && other->status != Deleted) {
2878
0
      other->group = NULL;
2879
0
      peer_notify_unconfig(other);
2880
0
    } else
2881
0
      peer_notify_unconfig(peer);
2882
0
  }
2883
0
}
2884
2885
int peer_group_delete(struct peer_group *group)
2886
0
{
2887
0
  struct bgp *bgp;
2888
0
  struct peer *peer;
2889
0
  struct prefix *prefix;
2890
0
  struct peer *other;
2891
0
  struct listnode *node, *nnode;
2892
0
  afi_t afi;
2893
2894
0
  bgp = group->bgp;
2895
2896
0
  for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
2897
0
    other = peer->doppelganger;
2898
2899
0
    if (CHECK_FLAG(peer->flags, PEER_FLAG_CAPABILITY_ENHE))
2900
0
      bgp_zebra_terminate_radv(bgp, peer);
2901
2902
0
    peer_delete(peer);
2903
0
    if (other && other->status != Deleted) {
2904
0
      other->group = NULL;
2905
0
      peer_delete(other);
2906
0
    }
2907
0
  }
2908
0
  list_delete(&group->peer);
2909
2910
0
  for (afi = AFI_IP; afi < AFI_MAX; afi++) {
2911
0
    for (ALL_LIST_ELEMENTS(group->listen_range[afi], node, nnode,
2912
0
               prefix)) {
2913
0
      prefix_free(&prefix);
2914
0
    }
2915
0
    list_delete(&group->listen_range[afi]);
2916
0
  }
2917
2918
0
  XFREE(MTYPE_PEER_GROUP_HOST, group->name);
2919
0
  group->name = NULL;
2920
2921
0
  if (group->conf->bfd_config)
2922
0
    bgp_peer_remove_bfd_config(group->conf);
2923
2924
0
  group->conf->group = NULL;
2925
0
  peer_delete(group->conf);
2926
2927
  /* Delete from all peer_group list. */
2928
0
  listnode_delete(bgp->group, group);
2929
2930
0
  peer_group_free(group);
2931
2932
0
  return 0;
2933
0
}
2934
2935
int peer_group_remote_as_delete(struct peer_group *group)
2936
0
{
2937
0
  struct peer *peer, *other;
2938
0
  struct listnode *node, *nnode;
2939
2940
0
  if ((group->conf->as_type == AS_UNSPECIFIED)
2941
0
      || ((!group->conf->as) && (group->conf->as_type == AS_SPECIFIED)))
2942
0
    return 0;
2943
2944
0
  for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
2945
0
    other = peer->doppelganger;
2946
2947
0
    if (CHECK_FLAG(peer->flags, PEER_FLAG_CAPABILITY_ENHE))
2948
0
      bgp_zebra_terminate_radv(peer->bgp, peer);
2949
2950
0
    peer_delete(peer);
2951
2952
0
    if (other && other->status != Deleted) {
2953
0
      other->group = NULL;
2954
0
      peer_delete(other);
2955
0
    }
2956
0
  }
2957
0
  list_delete_all_node(group->peer);
2958
2959
0
  group->conf->as = 0;
2960
0
  group->conf->as_type = AS_UNSPECIFIED;
2961
2962
0
  return 0;
2963
0
}
2964
2965
int peer_group_listen_range_add(struct peer_group *group, struct prefix *range)
2966
0
{
2967
0
  struct prefix *prefix;
2968
0
  struct listnode *node, *nnode;
2969
0
  afi_t afi;
2970
2971
0
  afi = family2afi(range->family);
2972
2973
  /* Group needs remote AS configured. */
2974
0
  if (group->conf->as_type == AS_UNSPECIFIED)
2975
0
    return BGP_ERR_PEER_GROUP_NO_REMOTE_AS;
2976
2977
  /* Ensure no duplicates. Currently we don't care about overlaps. */
2978
0
  for (ALL_LIST_ELEMENTS(group->listen_range[afi], node, nnode, prefix)) {
2979
0
    if (prefix_same(range, prefix))
2980
0
      return 0;
2981
0
  }
2982
2983
0
  prefix = prefix_new();
2984
0
  prefix_copy(prefix, range);
2985
0
  listnode_add(group->listen_range[afi], prefix);
2986
2987
  /* Update passwords for new ranges */
2988
0
  if (group->conf->password)
2989
0
    bgp_md5_set_prefix(group->bgp, prefix, group->conf->password);
2990
2991
0
  return 0;
2992
0
}
2993
2994
int peer_group_listen_range_del(struct peer_group *group, struct prefix *range)
2995
0
{
2996
0
  struct prefix *prefix, prefix2;
2997
0
  struct listnode *node, *nnode;
2998
0
  struct peer *peer;
2999
0
  afi_t afi;
3000
3001
0
  afi = family2afi(range->family);
3002
3003
  /* Identify the listen range. */
3004
0
  for (ALL_LIST_ELEMENTS(group->listen_range[afi], node, nnode, prefix)) {
3005
0
    if (prefix_same(range, prefix))
3006
0
      break;
3007
0
  }
3008
3009
0
  if (!prefix)
3010
0
    return BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_NOT_FOUND;
3011
3012
  /* Dispose off any dynamic neighbors that exist due to this listen range
3013
   */
3014
0
  for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
3015
0
    if (!peer_dynamic_neighbor(peer))
3016
0
      continue;
3017
3018
0
    if (sockunion2hostprefix(&peer->su, &prefix2)
3019
0
        && prefix_match(prefix, &prefix2)) {
3020
0
      if (bgp_debug_neighbor_events(peer))
3021
0
        zlog_debug(
3022
0
          "Deleting dynamic neighbor %s group %s upon delete of listen range %pFX",
3023
0
          peer->host, group->name, prefix);
3024
0
      peer_delete(peer);
3025
0
    }
3026
0
  }
3027
3028
  /* Get rid of the listen range */
3029
0
  listnode_delete(group->listen_range[afi], prefix);
3030
3031
  /* Remove passwords for deleted ranges */
3032
0
  if (group->conf->password)
3033
0
    bgp_md5_unset_prefix(group->bgp, prefix);
3034
3035
0
  return 0;
3036
0
}
3037
3038
/* Bind specified peer to peer group.  */
3039
int peer_group_bind(struct bgp *bgp, union sockunion *su, struct peer *peer,
3040
        struct peer_group *group, as_t *as)
3041
0
{
3042
0
  int first_member = 0;
3043
0
  afi_t afi;
3044
0
  safi_t safi;
3045
0
  enum bgp_peer_sort ptype, gtype;
3046
3047
  /* Lookup the peer.  */
3048
0
  if (!peer)
3049
0
    peer = peer_lookup(bgp, su);
3050
3051
  /* The peer exist, bind it to the peer-group */
3052
0
  if (peer) {
3053
    /* When the peer already belongs to a peer-group, check the
3054
     * consistency.  */
3055
0
    if (peer_group_active(peer)) {
3056
3057
      /* The peer is already bound to the peer-group,
3058
       * nothing to do
3059
       */
3060
0
      if (strcmp(peer->group->name, group->name) == 0)
3061
0
        return 0;
3062
0
      else
3063
0
        return BGP_ERR_PEER_GROUP_CANT_CHANGE;
3064
0
    }
3065
3066
    /* The peer has not specified a remote-as, inherit it from the
3067
     * peer-group */
3068
0
    if (peer->as_type == AS_UNSPECIFIED) {
3069
0
      peer->as_type = group->conf->as_type;
3070
0
      peer->as = group->conf->as;
3071
0
      peer->sort = group->conf->sort;
3072
0
    }
3073
3074
0
    ptype = peer_sort(peer);
3075
0
    if (!group->conf->as && ptype != BGP_PEER_UNSPECIFIED) {
3076
0
      gtype = peer_sort(group->conf);
3077
0
      if ((gtype != BGP_PEER_INTERNAL) && (gtype != ptype)) {
3078
0
        if (as)
3079
0
          *as = peer->as;
3080
0
        return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT;
3081
0
      }
3082
3083
0
      if (gtype == BGP_PEER_INTERNAL)
3084
0
        first_member = 1;
3085
0
    }
3086
3087
0
    peer_group2peer_config_copy(group, peer);
3088
3089
0
    FOREACH_AFI_SAFI (afi, safi) {
3090
0
      if (group->conf->afc[afi][safi]) {
3091
0
        peer->afc[afi][safi] = 1;
3092
3093
0
        if (peer_af_find(peer, afi, safi)
3094
0
            || peer_af_create(peer, afi, safi)) {
3095
0
          peer_group2peer_config_copy_af(
3096
0
            group, peer, afi, safi);
3097
0
        }
3098
0
      } else if (peer->afc[afi][safi])
3099
0
        peer_deactivate(peer, afi, safi);
3100
0
    }
3101
3102
0
    if (peer->group) {
3103
0
      assert(group && peer->group == group);
3104
0
    } else {
3105
0
      listnode_delete(bgp->peer, peer);
3106
3107
0
      peer->group = group;
3108
0
      listnode_add_sort(bgp->peer, peer);
3109
3110
0
      peer = peer_lock(peer); /* group->peer list reference */
3111
0
      listnode_add(group->peer, peer);
3112
0
    }
3113
3114
0
    if (first_member) {
3115
0
      gtype = peer_sort(group->conf);
3116
      /* Advertisement-interval reset */
3117
0
      if (!CHECK_FLAG(group->conf->flags,
3118
0
          PEER_FLAG_ROUTEADV)) {
3119
0
        group->conf->v_routeadv =
3120
0
          (gtype == BGP_PEER_IBGP)
3121
0
            ? BGP_DEFAULT_IBGP_ROUTEADV
3122
0
            : BGP_DEFAULT_EBGP_ROUTEADV;
3123
0
      }
3124
3125
      /* ebgp-multihop reset */
3126
0
      if (gtype == BGP_PEER_IBGP)
3127
0
        group->conf->ttl = MAXTTL;
3128
0
    }
3129
3130
0
    SET_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE);
3131
3132
0
    if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
3133
0
      peer->last_reset = PEER_DOWN_RMAP_BIND;
3134
0
      bgp_notify_send(peer, BGP_NOTIFY_CEASE,
3135
0
          BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3136
0
    } else {
3137
0
      bgp_session_reset(peer);
3138
0
    }
3139
0
  }
3140
3141
  /* Create a new peer. */
3142
0
  else {
3143
0
    if ((group->conf->as_type == AS_SPECIFIED)
3144
0
        && (!group->conf->as)) {
3145
0
      return BGP_ERR_PEER_GROUP_NO_REMOTE_AS;
3146
0
    }
3147
3148
0
    peer = peer_create(su, NULL, bgp, bgp->as, group->conf->as,
3149
0
           group->conf->as_type, group, true, NULL);
3150
3151
0
    peer = peer_lock(peer); /* group->peer list reference */
3152
0
    listnode_add(group->peer, peer);
3153
3154
0
    peer_group2peer_config_copy(group, peer);
3155
3156
    /* If the peer-group is active for this afi/safi then activate
3157
     * for this peer */
3158
0
    FOREACH_AFI_SAFI (afi, safi) {
3159
0
      if (group->conf->afc[afi][safi]) {
3160
0
        peer->afc[afi][safi] = 1;
3161
3162
0
        if (!peer_af_find(peer, afi, safi))
3163
0
          peer_af_create(peer, afi, safi);
3164
3165
0
        peer_group2peer_config_copy_af(group, peer, afi,
3166
0
                     safi);
3167
0
      } else if (peer->afc[afi][safi])
3168
0
        peer_deactivate(peer, afi, safi);
3169
0
    }
3170
3171
    /* Set up peer's events and timers. */
3172
0
    if (peer_active(peer))
3173
0
      bgp_timer_set(peer);
3174
0
  }
3175
3176
0
  return 0;
3177
0
}
3178
3179
static void bgp_startup_timer_expire(struct event *thread)
3180
0
{
3181
0
  struct bgp *bgp;
3182
0
3183
0
  bgp = EVENT_ARG(thread);
3184
0
  bgp->t_startup = NULL;
3185
0
}
3186
3187
/*
3188
 * On shutdown we call the cleanup function which
3189
 * does a free of the link list nodes,  free up
3190
 * the data we are pointing at too.
3191
 */
3192
static void bgp_vrf_string_name_delete(void *data)
3193
0
{
3194
0
  char *vname = data;
3195
3196
0
  XFREE(MTYPE_TMP, vname);
3197
0
}
3198
3199
/* BGP instance creation by `router bgp' commands. */
3200
static struct bgp *bgp_create(as_t *as, const char *name,
3201
            enum bgp_instance_type inst_type,
3202
            const char *as_pretty,
3203
            enum asnotation_mode asnotation)
3204
1
{
3205
1
  struct bgp *bgp;
3206
1
  afi_t afi;
3207
1
  safi_t safi;
3208
3209
1
  bgp = XCALLOC(MTYPE_BGP, sizeof(struct bgp));
3210
1
  bgp->as = *as;
3211
1
  if (as_pretty)
3212
0
    bgp->as_pretty = XSTRDUP(MTYPE_BGP, as_pretty);
3213
1
  else
3214
1
    bgp->as_pretty = XSTRDUP(MTYPE_BGP, asn_asn2asplain(*as));
3215
3216
1
  if (asnotation != ASNOTATION_UNDEFINED) {
3217
0
    bgp->asnotation = asnotation;
3218
0
    SET_FLAG(bgp->config, BGP_CONFIG_ASNOTATION);
3219
0
  } else
3220
1
    asn_str2asn_notation(bgp->as_pretty, NULL, &bgp->asnotation);
3221
3222
1
  if (BGP_DEBUG(zebra, ZEBRA)) {
3223
0
    if (inst_type == BGP_INSTANCE_TYPE_DEFAULT)
3224
0
      zlog_debug("Creating Default VRF, AS %s",
3225
0
           bgp->as_pretty);
3226
0
    else
3227
0
      zlog_debug("Creating %s %s, AS %s",
3228
0
           (inst_type == BGP_INSTANCE_TYPE_VRF)
3229
0
             ? "VRF"
3230
0
             : "VIEW",
3231
0
           name, bgp->as_pretty);
3232
0
  }
3233
3234
  /* Default the EVPN VRF to the default one */
3235
1
  if (inst_type == BGP_INSTANCE_TYPE_DEFAULT && !bgp_master.bgp_evpn) {
3236
1
    bgp_lock(bgp);
3237
1
    bm->bgp_evpn = bgp;
3238
1
  }
3239
3240
1
  bgp_lock(bgp);
3241
3242
1
  bgp->allow_martian = false;
3243
1
  bgp_process_queue_init(bgp);
3244
1
  bgp->heuristic_coalesce = true;
3245
1
  bgp->inst_type = inst_type;
3246
1
  bgp->vrf_id = (inst_type == BGP_INSTANCE_TYPE_DEFAULT) ? VRF_DEFAULT
3247
1
                     : VRF_UNKNOWN;
3248
1
  bgp->peer_self = peer_new(bgp);
3249
1
  XFREE(MTYPE_BGP_PEER_HOST, bgp->peer_self->host);
3250
1
  bgp->peer_self->host =
3251
1
    XSTRDUP(MTYPE_BGP_PEER_HOST, "Static announcement");
3252
1
  XFREE(MTYPE_BGP_PEER_HOST, bgp->peer_self->hostname);
3253
1
  if (cmd_hostname_get())
3254
1
    bgp->peer_self->hostname =
3255
1
      XSTRDUP(MTYPE_BGP_PEER_HOST, cmd_hostname_get());
3256
3257
1
  XFREE(MTYPE_BGP_PEER_HOST, bgp->peer_self->domainname);
3258
1
  if (cmd_domainname_get())
3259
0
    bgp->peer_self->domainname =
3260
0
      XSTRDUP(MTYPE_BGP_PEER_HOST, cmd_domainname_get());
3261
1
  bgp->peer = list_new();
3262
1
  bgp->peer->cmp = (int (*)(void *, void *))peer_cmp;
3263
1
  bgp->peerhash = hash_create(peer_hash_key_make, peer_hash_same,
3264
1
            "BGP Peer Hash");
3265
1
  bgp->peerhash->max_size = BGP_PEER_MAX_HASH_SIZE;
3266
3267
1
  bgp->group = list_new();
3268
1
  bgp->group->cmp = (int (*)(void *, void *))peer_group_cmp;
3269
3270
21
  FOREACH_AFI_SAFI (afi, safi) {
3271
21
    bgp->route[afi][safi] = bgp_table_init(bgp, afi, safi);
3272
21
    bgp->aggregate[afi][safi] = bgp_table_init(bgp, afi, safi);
3273
21
    bgp->rib[afi][safi] = bgp_table_init(bgp, afi, safi);
3274
3275
    /* Enable maximum-paths */
3276
21
    bgp_maximum_paths_set(bgp, afi, safi, BGP_PEER_EBGP,
3277
21
              multipath_num, 0);
3278
21
    bgp_maximum_paths_set(bgp, afi, safi, BGP_PEER_IBGP,
3279
21
              multipath_num, 0);
3280
    /* Initialize graceful restart info */
3281
21
    bgp->gr_info[afi][safi].eor_required = 0;
3282
21
    bgp->gr_info[afi][safi].eor_received = 0;
3283
21
    bgp->gr_info[afi][safi].t_select_deferral = NULL;
3284
21
    bgp->gr_info[afi][safi].t_route_select = NULL;
3285
21
    bgp->gr_info[afi][safi].gr_deferred = 0;
3286
21
  }
3287
3288
1
  bgp->v_update_delay = bm->v_update_delay;
3289
1
  bgp->v_establish_wait = bm->v_establish_wait;
3290
1
  bgp->default_local_pref = BGP_DEFAULT_LOCAL_PREF;
3291
1
  bgp->default_subgroup_pkt_queue_max =
3292
1
    BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX;
3293
1
  bgp_tcp_keepalive_unset(bgp);
3294
1
  bgp_timers_unset(bgp);
3295
1
  bgp->default_min_holdtime = 0;
3296
1
  bgp->restart_time = BGP_DEFAULT_RESTART_TIME;
3297
1
  bgp->stalepath_time = BGP_DEFAULT_STALEPATH_TIME;
3298
1
  bgp->select_defer_time = BGP_DEFAULT_SELECT_DEFERRAL_TIME;
3299
1
  bgp->rib_stale_time = BGP_DEFAULT_RIB_STALE_TIME;
3300
1
  bgp->dynamic_neighbors_limit = BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT;
3301
1
  bgp->dynamic_neighbors_count = 0;
3302
1
  bgp->lb_ref_bw = BGP_LINK_BW_REF_BW;
3303
1
  bgp->lb_handling = BGP_LINK_BW_ECMP;
3304
1
  bgp->reject_as_sets = false;
3305
1
  bgp->condition_check_period = DEFAULT_CONDITIONAL_ROUTES_POLL_TIME;
3306
1
  bgp_addpath_init_bgp_data(&bgp->tx_addpath);
3307
1
  bgp->fast_convergence = false;
3308
1
  bgp->llgr_stale_time = BGP_DEFAULT_LLGR_STALE_TIME;
3309
3310
1
#ifdef ENABLE_BGP_VNC
3311
1
  if (inst_type != BGP_INSTANCE_TYPE_VRF) {
3312
1
    bgp->rfapi = bgp_rfapi_new(bgp);
3313
1
    assert(bgp->rfapi);
3314
1
    assert(bgp->rfapi_cfg);
3315
1
  }
3316
1
#endif /* ENABLE_BGP_VNC */
3317
3318
4
  for (afi = AFI_IP; afi < AFI_MAX; afi++) {
3319
3
    bgp->vpn_policy[afi].bgp = bgp;
3320
3
    bgp->vpn_policy[afi].afi = afi;
3321
3
    bgp->vpn_policy[afi].tovpn_label = MPLS_LABEL_NONE;
3322
3
    bgp->vpn_policy[afi].tovpn_zebra_vrf_label_last_sent =
3323
3
      MPLS_LABEL_NONE;
3324
3325
3
    bgp->vpn_policy[afi].import_vrf = list_new();
3326
3
    bgp->vpn_policy[afi].import_vrf->del =
3327
3
      bgp_vrf_string_name_delete;
3328
3
    bgp->vpn_policy[afi].export_vrf = list_new();
3329
3
    bgp->vpn_policy[afi].export_vrf->del =
3330
3
      bgp_vrf_string_name_delete;
3331
3
    SET_FLAG(bgp->af_flags[afi][SAFI_MPLS_VPN],
3332
3
       BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL);
3333
3
  }
3334
3335
4
  for (afi = AFI_IP; afi < AFI_MAX; afi++)
3336
3
    bgp_label_per_nexthop_cache_init(
3337
3
      &bgp->mpls_labels_per_nexthop[afi]);
3338
3339
1
  if (name)
3340
1
    bgp->name = XSTRDUP(MTYPE_BGP, name);
3341
3342
1
  event_add_timer(bm->master, bgp_startup_timer_expire, bgp,
3343
1
      bgp->restart_time, &bgp->t_startup);
3344
3345
  /* printable name we can use in debug messages */
3346
1
  if (inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
3347
1
    bgp->name_pretty = XSTRDUP(MTYPE_BGP, "VRF default");
3348
1
  } else {
3349
0
    const char *n;
3350
0
    int len;
3351
3352
0
    if (bgp->name)
3353
0
      n = bgp->name;
3354
0
    else
3355
0
      n = "?";
3356
3357
0
    len = 4 + 1 + strlen(n) + 1;  /* "view foo\0" */
3358
3359
0
    bgp->name_pretty = XCALLOC(MTYPE_BGP, len);
3360
0
    snprintf(bgp->name_pretty, len, "%s %s",
3361
0
      (bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
3362
0
        ? "VRF"
3363
0
        : "VIEW",
3364
0
      n);
3365
0
  }
3366
3367
1
  atomic_store_explicit(&bgp->wpkt_quanta, BGP_WRITE_PACKET_MAX,
3368
1
            memory_order_relaxed);
3369
1
  atomic_store_explicit(&bgp->rpkt_quanta, BGP_READ_PACKET_MAX,
3370
1
            memory_order_relaxed);
3371
1
  bgp->coalesce_time = BGP_DEFAULT_SUBGROUP_COALESCE_TIME;
3372
1
  bgp->default_af[AFI_IP][SAFI_UNICAST] = true;
3373
3374
1
  QOBJ_REG(bgp, bgp);
3375
3376
1
  update_bgp_group_init(bgp);
3377
3378
  /* assign a unique rd id for auto derivation of vrf's RD */
3379
1
  bf_assign_index(bm->rd_idspace, bgp->vrf_rd_id);
3380
3381
1
  bgp->evpn_info = XCALLOC(MTYPE_BGP_EVPN_INFO,
3382
1
         sizeof(struct bgp_evpn_info));
3383
1
  bgp_evpn_init(bgp);
3384
1
  bgp_evpn_vrf_es_init(bgp);
3385
1
  bgp_pbr_init(bgp);
3386
1
  bgp_srv6_init(bgp);
3387
3388
  /*initilize global GR FSM */
3389
1
  bgp_global_gr_init(bgp);
3390
3391
1
  memset(&bgp->ebgprequirespolicywarning, 0,
3392
1
         sizeof(bgp->ebgprequirespolicywarning));
3393
3394
1
  return bgp;
3395
1
}
3396
3397
/* Return the "default VRF" instance of BGP. */
3398
struct bgp *bgp_get_default(void)
3399
353
{
3400
353
  struct bgp *bgp;
3401
353
  struct listnode *node, *nnode;
3402
3403
353
  for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
3404
353
    if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
3405
353
      return bgp;
3406
0
  return NULL;
3407
353
}
3408
3409
/* Lookup BGP entry. */
3410
struct bgp *bgp_lookup(as_t as, const char *name)
3411
0
{
3412
0
  struct bgp *bgp;
3413
0
  struct listnode *node, *nnode;
3414
3415
0
  for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
3416
0
    if (bgp->as == as
3417
0
        && ((bgp->name == NULL && name == NULL)
3418
0
      || (bgp->name && name && strcmp(bgp->name, name) == 0)))
3419
0
      return bgp;
3420
0
  return NULL;
3421
0
}
3422
3423
/* Lookup BGP structure by view name. */
3424
struct bgp *bgp_lookup_by_name(const char *name)
3425
1
{
3426
1
  struct bgp *bgp;
3427
1
  struct listnode *node, *nnode;
3428
3429
1
  for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
3430
0
    if ((bgp->name == NULL && name == NULL)
3431
0
        || (bgp->name && name && strcmp(bgp->name, name) == 0))
3432
0
      return bgp;
3433
1
  return NULL;
3434
1
}
3435
3436
/* Lookup BGP instance based on VRF id. */
3437
/* Note: Only to be used for incoming messages from Zebra. */
3438
struct bgp *bgp_lookup_by_vrf_id(vrf_id_t vrf_id)
3439
0
{
3440
0
  struct vrf *vrf;
3441
3442
  /* Lookup VRF (in tree) and follow link. */
3443
0
  vrf = vrf_lookup_by_id(vrf_id);
3444
0
  if (!vrf)
3445
0
    return NULL;
3446
0
  return (vrf->info) ? (struct bgp *)vrf->info : NULL;
3447
0
}
3448
3449
/* Sets the BGP instance where EVPN is enabled */
3450
void bgp_set_evpn(struct bgp *bgp)
3451
0
{
3452
0
  if (bm->bgp_evpn == bgp)
3453
0
    return;
3454
3455
  /* First, release the reference count we hold on the instance */
3456
0
  if (bm->bgp_evpn)
3457
0
    bgp_unlock(bm->bgp_evpn);
3458
3459
0
  bm->bgp_evpn = bgp;
3460
3461
  /* Increase the reference count on this new VRF */
3462
0
  if (bm->bgp_evpn)
3463
0
    bgp_lock(bm->bgp_evpn);
3464
0
}
3465
3466
/* Returns the BGP instance where EVPN is enabled, if any */
3467
struct bgp *bgp_get_evpn(void)
3468
0
{
3469
0
  return bm->bgp_evpn;
3470
0
}
3471
3472
/* handle socket creation or deletion, if necessary
3473
 * this is called for all new BGP instances
3474
 */
3475
int bgp_handle_socket(struct bgp *bgp, struct vrf *vrf, vrf_id_t old_vrf_id,
3476
          bool create)
3477
1
{
3478
1
  struct listnode *node;
3479
1
  char *address;
3480
3481
  /* Create BGP server socket, if listen mode not disabled */
3482
1
  if (!bgp || bgp_option_check(BGP_OPT_NO_LISTEN))
3483
1
    return 0;
3484
0
  if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF) {
3485
    /*
3486
     * suppress vrf socket
3487
     */
3488
0
    if (!create) {
3489
0
      bgp_close_vrf_socket(bgp);
3490
0
      return 0;
3491
0
    }
3492
0
    if (vrf == NULL)
3493
0
      return BGP_ERR_INVALID_VALUE;
3494
    /* do nothing
3495
     * if vrf_id did not change
3496
     */
3497
0
    if (vrf->vrf_id == old_vrf_id)
3498
0
      return 0;
3499
0
    if (old_vrf_id != VRF_UNKNOWN) {
3500
      /* look for old socket. close it. */
3501
0
      bgp_close_vrf_socket(bgp);
3502
0
    }
3503
    /* if backend is not yet identified ( VRF_UNKNOWN) then
3504
     *   creation will be done later
3505
     */
3506
0
    if (vrf->vrf_id == VRF_UNKNOWN)
3507
0
      return 0;
3508
0
    if (list_isempty(bm->addresses)) {
3509
0
      if (bgp_socket(bgp, bm->port, NULL) < 0)
3510
0
        return BGP_ERR_INVALID_VALUE;
3511
0
    } else {
3512
0
      for (ALL_LIST_ELEMENTS_RO(bm->addresses, node, address))
3513
0
        if (bgp_socket(bgp, bm->port, address) < 0)
3514
0
          return BGP_ERR_INVALID_VALUE;
3515
0
    }
3516
0
    return 0;
3517
0
  } else
3518
0
    return bgp_check_main_socket(create, bgp);
3519
0
}
3520
3521
int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as, const char *name,
3522
             enum bgp_instance_type inst_type)
3523
1
{
3524
1
  struct bgp *bgp;
3525
3526
  /* Multiple instance check. */
3527
1
  if (name)
3528
1
    bgp = bgp_lookup_by_name(name);
3529
0
  else
3530
0
    bgp = bgp_get_default();
3531
3532
1
  if (bgp) {
3533
0
    *bgp_val = bgp;
3534
0
    if (bgp->as != *as) {
3535
0
      *as = bgp->as;
3536
0
      return BGP_ERR_AS_MISMATCH;
3537
0
    }
3538
0
    if (bgp->inst_type != inst_type)
3539
0
      return BGP_ERR_INSTANCE_MISMATCH;
3540
0
    return BGP_SUCCESS;
3541
0
  }
3542
1
  *bgp_val = NULL;
3543
3544
1
  return BGP_SUCCESS;
3545
1
}
3546
3547
/* Called from VTY commands. */
3548
int bgp_get(struct bgp **bgp_val, as_t *as, const char *name,
3549
      enum bgp_instance_type inst_type, const char *as_pretty,
3550
      enum asnotation_mode asnotation)
3551
1
{
3552
1
  struct bgp *bgp;
3553
1
  struct vrf *vrf = NULL;
3554
1
  int ret = 0;
3555
3556
1
  ret = bgp_lookup_by_as_name_type(bgp_val, as, name, inst_type);
3557
1
  if (ret || *bgp_val)
3558
0
    return ret;
3559
3560
1
  bgp = bgp_create(as, name, inst_type, as_pretty, asnotation);
3561
3562
  /*
3563
   * view instances will never work inside of a vrf
3564
   * as such they must always be in the VRF_DEFAULT
3565
   * Also we must set this to something useful because
3566
   * of the vrf socket code needing an actual useful
3567
   * default value to send to the underlying OS.
3568
   *
3569
   * This code is currently ignoring vrf based
3570
   * code using the -Z option( and that is probably
3571
   * best addressed elsewhere in the code )
3572
   */
3573
1
  if (inst_type == BGP_INSTANCE_TYPE_VIEW)
3574
0
    bgp->vrf_id = VRF_DEFAULT;
3575
3576
1
  bgp_router_id_set(bgp, &bgp->router_id_zebra, true);
3577
1
  bgp_address_init(bgp);
3578
1
  bgp_tip_hash_init(bgp);
3579
1
  bgp_scan_init(bgp);
3580
1
  *bgp_val = bgp;
3581
3582
1
  bgp->t_rmap_def_originate_eval = NULL;
3583
3584
  /* If Default instance or VRF, link to the VRF structure, if present. */
3585
1
  if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
3586
1
      || bgp->inst_type == BGP_INSTANCE_TYPE_VRF) {
3587
1
    vrf = bgp_vrf_lookup_by_instance_type(bgp);
3588
1
    if (vrf)
3589
0
      bgp_vrf_link(bgp, vrf);
3590
1
  }
3591
  /* BGP server socket already processed if BGP instance
3592
   * already part of the list
3593
   */
3594
1
  bgp_handle_socket(bgp, vrf, VRF_UNKNOWN, true);
3595
1
  listnode_add(bm->bgp, bgp);
3596
3597
1
  if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) {
3598
1
    if (BGP_DEBUG(zebra, ZEBRA))
3599
0
      zlog_debug("%s: Registering BGP instance %s to zebra",
3600
1
           __func__, bgp->name_pretty);
3601
1
    bgp_zebra_instance_register(bgp);
3602
1
  }
3603
3604
1
  return BGP_CREATED;
3605
1
}
3606
3607
static void bgp_zclient_set_redist(afi_t afi, int type, unsigned short instance,
3608
           vrf_id_t vrf_id, bool set)
3609
0
{
3610
0
  if (instance) {
3611
0
    if (set)
3612
0
      redist_add_instance(&zclient->mi_redist[afi][type],
3613
0
              instance);
3614
0
    else
3615
0
      redist_del_instance(&zclient->mi_redist[afi][type],
3616
0
              instance);
3617
0
  } else {
3618
0
    if (set)
3619
0
      vrf_bitmap_set(zclient->redist[afi][type], vrf_id);
3620
0
    else
3621
0
      vrf_bitmap_unset(zclient->redist[afi][type], vrf_id);
3622
0
  }
3623
0
}
3624
3625
static void bgp_set_redist_vrf_bitmaps(struct bgp *bgp, bool set)
3626
0
{
3627
0
  afi_t afi;
3628
0
  int i;
3629
0
  struct list *red_list;
3630
0
  struct listnode *node;
3631
0
  struct bgp_redist *red;
3632
3633
0
  for (afi = AFI_IP; afi < AFI_MAX; afi++) {
3634
0
    for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
3635
3636
0
      red_list = bgp->redist[afi][i];
3637
0
      if (!red_list)
3638
0
        continue;
3639
3640
0
      for (ALL_LIST_ELEMENTS_RO(red_list, node, red))
3641
0
        bgp_zclient_set_redist(afi, i, red->instance,
3642
0
                   bgp->vrf_id, set);
3643
0
    }
3644
0
  }
3645
0
}
3646
3647
/*
3648
 * Make BGP instance "up". Applies only to VRFs (non-default) and
3649
 * implies the VRF has been learnt from Zebra.
3650
 */
3651
void bgp_instance_up(struct bgp *bgp)
3652
0
{
3653
0
  struct peer *peer;
3654
0
  struct listnode *node, *next;
3655
3656
0
  bgp_set_redist_vrf_bitmaps(bgp, true);
3657
3658
  /* Register with zebra. */
3659
0
  bgp_zebra_instance_register(bgp);
3660
3661
  /* Kick off any peers that may have been configured. */
3662
0
  for (ALL_LIST_ELEMENTS(bgp->peer, node, next, peer)) {
3663
0
    if (!BGP_PEER_START_SUPPRESSED(peer))
3664
0
      BGP_EVENT_ADD(peer, BGP_Start);
3665
0
  }
3666
3667
  /* Process any networks that have been configured. */
3668
0
  bgp_static_add(bgp);
3669
0
}
3670
3671
/*
3672
 * Make BGP instance "down". Applies only to VRFs (non-default) and
3673
 * implies the VRF has been deleted by Zebra.
3674
 */
3675
void bgp_instance_down(struct bgp *bgp)
3676
0
{
3677
0
  struct peer *peer;
3678
0
  struct listnode *node;
3679
0
  struct listnode *next;
3680
3681
  /* Stop timers. */
3682
0
  if (bgp->t_rmap_def_originate_eval) {
3683
0
    EVENT_OFF(bgp->t_rmap_def_originate_eval);
3684
0
    bgp_unlock(bgp); /* TODO - This timer is started with a lock -
3685
            why? */
3686
0
  }
3687
3688
  /* Bring down peers, so corresponding routes are purged. */
3689
0
  for (ALL_LIST_ELEMENTS(bgp->peer, node, next, peer)) {
3690
0
    if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
3691
0
      bgp_notify_send(peer, BGP_NOTIFY_CEASE,
3692
0
          BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
3693
0
    else
3694
0
      bgp_session_reset(peer);
3695
0
  }
3696
3697
  /* Purge network and redistributed routes. */
3698
0
  bgp_purge_static_redist_routes(bgp);
3699
3700
  /* Cleanup registered nexthops (flags) */
3701
0
  bgp_cleanup_nexthops(bgp);
3702
3703
0
  bgp_zebra_instance_deregister(bgp);
3704
3705
0
  bgp_set_redist_vrf_bitmaps(bgp, false);
3706
0
}
3707
3708
/* Delete BGP instance. */
3709
int bgp_delete(struct bgp *bgp)
3710
0
{
3711
0
  struct peer *peer;
3712
0
  struct peer_group *group;
3713
0
  struct listnode *node, *next;
3714
0
  struct vrf *vrf;
3715
0
  afi_t afi;
3716
0
  safi_t safi;
3717
0
  int i;
3718
0
  struct graceful_restart_info *gr_info;
3719
3720
0
  assert(bgp);
3721
3722
0
  bgp_soft_reconfig_table_task_cancel(bgp, NULL, NULL);
3723
3724
  /* make sure we withdraw any exported routes */
3725
0
  vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, AFI_IP, bgp_get_default(),
3726
0
         bgp);
3727
0
  vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, AFI_IP6, bgp_get_default(),
3728
0
         bgp);
3729
3730
0
  bgp_vpn_leak_unimport(bgp);
3731
3732
0
  hook_call(bgp_inst_delete, bgp);
3733
3734
0
  FOREACH_AFI_SAFI (afi, safi)
3735
0
    EVENT_OFF(bgp->t_revalidate[afi][safi]);
3736
3737
0
  EVENT_OFF(bgp->t_condition_check);
3738
0
  EVENT_OFF(bgp->t_startup);
3739
0
  EVENT_OFF(bgp->t_maxmed_onstartup);
3740
0
  EVENT_OFF(bgp->t_update_delay);
3741
0
  EVENT_OFF(bgp->t_establish_wait);
3742
3743
  /* Set flag indicating bgp instance delete in progress */
3744
0
  SET_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS);
3745
3746
  /* Delete the graceful restart info */
3747
0
  FOREACH_AFI_SAFI (afi, safi) {
3748
0
    struct event *t;
3749
3750
0
    gr_info = &bgp->gr_info[afi][safi];
3751
0
    if (!gr_info)
3752
0
      continue;
3753
0
    t = gr_info->t_select_deferral;
3754
0
    if (t) {
3755
0
      void *info = EVENT_ARG(t);
3756
3757
0
      XFREE(MTYPE_TMP, info);
3758
0
    }
3759
0
    EVENT_OFF(gr_info->t_select_deferral);
3760
3761
0
    t = gr_info->t_route_select;
3762
0
    if (t) {
3763
0
      void *info = EVENT_ARG(t);
3764
3765
0
      XFREE(MTYPE_TMP, info);
3766
0
    }
3767
0
    EVENT_OFF(gr_info->t_route_select);
3768
0
  }
3769
3770
0
  if (BGP_DEBUG(zebra, ZEBRA)) {
3771
0
    if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
3772
0
      zlog_debug("Deleting Default VRF");
3773
0
    else
3774
0
      zlog_debug("Deleting %s %s",
3775
0
           (bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
3776
0
             ? "VRF"
3777
0
             : "VIEW",
3778
0
           bgp->name);
3779
0
  }
3780
3781
  /* unmap from RT list */
3782
0
  bgp_evpn_vrf_delete(bgp);
3783
3784
  /* unmap bgp vrf label */
3785
0
  vpn_leak_zebra_vrf_label_withdraw(bgp, AFI_IP);
3786
0
  vpn_leak_zebra_vrf_label_withdraw(bgp, AFI_IP6);
3787
3788
  /* Stop timers. */
3789
0
  if (bgp->t_rmap_def_originate_eval) {
3790
0
    EVENT_OFF(bgp->t_rmap_def_originate_eval);
3791
0
    bgp_unlock(bgp); /* TODO - This timer is started with a lock -
3792
            why? */
3793
0
  }
3794
3795
  /* Inform peers we're going down. */
3796
0
  for (ALL_LIST_ELEMENTS(bgp->peer, node, next, peer))
3797
0
    peer_notify_shutdown(peer);
3798
3799
  /* Delete static routes (networks). */
3800
0
  bgp_static_delete(bgp);
3801
3802
  /* Unset redistribution. */
3803
0
  for (afi = AFI_IP; afi < AFI_MAX; afi++)
3804
0
    for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
3805
0
      if (i != ZEBRA_ROUTE_BGP)
3806
0
        bgp_redistribute_unset(bgp, afi, i, 0);
3807
3808
  /* Free peers and peer-groups. */
3809
0
  for (ALL_LIST_ELEMENTS(bgp->group, node, next, group))
3810
0
    peer_group_delete(group);
3811
3812
0
  while (listcount(bgp->peer)) {
3813
0
    peer = listnode_head(bgp->peer);
3814
0
    peer_delete(peer);
3815
0
  }
3816
3817
0
  if (bgp->peer_self) {
3818
0
    peer_delete(bgp->peer_self);
3819
0
    bgp->peer_self = NULL;
3820
0
  }
3821
3822
0
  update_bgp_group_free(bgp);
3823
3824
/* TODO - Other memory may need to be freed - e.g., NHT */
3825
3826
0
#ifdef ENABLE_BGP_VNC
3827
0
  rfapi_delete(bgp);
3828
0
#endif
3829
3830
  /* Free memory allocated with aggregate address configuration. */
3831
0
  FOREACH_AFI_SAFI (afi, safi) {
3832
0
    struct bgp_aggregate *aggregate = NULL;
3833
3834
0
    for (struct bgp_dest *dest =
3835
0
           bgp_table_top(bgp->aggregate[afi][safi]);
3836
0
         dest; dest = bgp_route_next(dest)) {
3837
0
      aggregate = bgp_dest_get_bgp_aggregate_info(dest);
3838
0
      if (aggregate == NULL)
3839
0
        continue;
3840
3841
0
      bgp_dest_set_bgp_aggregate_info(dest, NULL);
3842
0
      bgp_free_aggregate_info(aggregate);
3843
0
    }
3844
0
  }
3845
3846
0
  bgp_cleanup_routes(bgp);
3847
3848
0
  for (afi = 0; afi < AFI_MAX; ++afi) {
3849
0
    if (!bgp->vpn_policy[afi].import_redirect_rtlist)
3850
0
      continue;
3851
0
    ecommunity_free(
3852
0
        &bgp->vpn_policy[afi]
3853
0
        .import_redirect_rtlist);
3854
0
    bgp->vpn_policy[afi].import_redirect_rtlist = NULL;
3855
0
  }
3856
3857
  /* Free any memory allocated to holding routemap references */
3858
0
  for (afi = 0; afi < AFI_MAX; ++afi) {
3859
0
    for (enum vpn_policy_direction dir = 0;
3860
0
         dir < BGP_VPN_POLICY_DIR_MAX; ++dir) {
3861
0
      if (bgp->vpn_policy[afi].rmap_name[dir])
3862
0
        XFREE(MTYPE_ROUTE_MAP_NAME,
3863
0
              bgp->vpn_policy[afi].rmap_name[dir]);
3864
0
      bgp->vpn_policy[afi].rmap[dir] = NULL;
3865
0
    }
3866
0
  }
3867
3868
  /* Deregister from Zebra, if needed */
3869
0
  if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) {
3870
0
    if (BGP_DEBUG(zebra, ZEBRA))
3871
0
      zlog_debug(
3872
0
        "%s: deregistering this bgp %s instance from zebra",
3873
0
        __func__, bgp->name);
3874
0
    bgp_zebra_instance_deregister(bgp);
3875
0
  }
3876
3877
  /* Remove visibility via the master list - there may however still be
3878
   * routes to be processed still referencing the struct bgp.
3879
   */
3880
0
  listnode_delete(bm->bgp, bgp);
3881
3882
  /* Free interfaces in this instance. */
3883
0
  bgp_if_finish(bgp);
3884
3885
0
  vrf = bgp_vrf_lookup_by_instance_type(bgp);
3886
0
  bgp_handle_socket(bgp, vrf, VRF_UNKNOWN, false);
3887
0
  if (vrf)
3888
0
    bgp_vrf_unlink(bgp, vrf);
3889
3890
  /* Update EVPN VRF pointer */
3891
0
  if (bm->bgp_evpn == bgp) {
3892
0
    if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
3893
0
      bgp_set_evpn(NULL);
3894
0
    else
3895
0
      bgp_set_evpn(bgp_get_default());
3896
0
  }
3897
3898
0
  if (bgp->process_queue)
3899
0
    work_queue_free_and_null(&bgp->process_queue);
3900
3901
0
  event_master_free_unused(bm->master);
3902
0
  bgp_unlock(bgp); /* initial reference */
3903
3904
0
  return 0;
3905
0
}
3906
3907
void bgp_free(struct bgp *bgp)
3908
0
{
3909
0
  afi_t afi;
3910
0
  safi_t safi;
3911
0
  struct bgp_table *table;
3912
0
  struct bgp_dest *dest;
3913
0
  struct bgp_rmap *rmap;
3914
3915
0
  QOBJ_UNREG(bgp);
3916
3917
0
  list_delete(&bgp->group);
3918
0
  list_delete(&bgp->peer);
3919
3920
0
  if (bgp->peerhash) {
3921
0
    hash_free(bgp->peerhash);
3922
0
    bgp->peerhash = NULL;
3923
0
  }
3924
3925
0
  FOREACH_AFI_SAFI (afi, safi) {
3926
    /* Special handling for 2-level routing tables. */
3927
0
    if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
3928
0
        || safi == SAFI_EVPN) {
3929
0
      for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
3930
0
           dest = bgp_route_next(dest)) {
3931
0
        table = bgp_dest_get_bgp_table_info(dest);
3932
0
        bgp_table_finish(&table);
3933
0
      }
3934
0
    }
3935
0
    if (bgp->route[afi][safi])
3936
0
      bgp_table_finish(&bgp->route[afi][safi]);
3937
0
    if (bgp->aggregate[afi][safi])
3938
0
      bgp_table_finish(&bgp->aggregate[afi][safi]);
3939
0
    if (bgp->rib[afi][safi])
3940
0
      bgp_table_finish(&bgp->rib[afi][safi]);
3941
0
    rmap = &bgp->table_map[afi][safi];
3942
0
    XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
3943
0
  }
3944
3945
0
  bgp_scan_finish(bgp);
3946
0
  bgp_address_destroy(bgp);
3947
0
  bgp_tip_hash_destroy(bgp);
3948
3949
  /* release the auto RD id */
3950
0
  bf_release_index(bm->rd_idspace, bgp->vrf_rd_id);
3951
3952
0
  bgp_evpn_cleanup(bgp);
3953
0
  bgp_pbr_cleanup(bgp);
3954
0
  XFREE(MTYPE_BGP_EVPN_INFO, bgp->evpn_info);
3955
3956
0
  for (afi = AFI_IP; afi < AFI_MAX; afi++) {
3957
0
    enum vpn_policy_direction dir;
3958
3959
0
    if (bgp->vpn_policy[afi].import_vrf)
3960
0
      list_delete(&bgp->vpn_policy[afi].import_vrf);
3961
0
    if (bgp->vpn_policy[afi].export_vrf)
3962
0
      list_delete(&bgp->vpn_policy[afi].export_vrf);
3963
3964
0
    dir = BGP_VPN_POLICY_DIR_FROMVPN;
3965
0
    if (bgp->vpn_policy[afi].rtlist[dir])
3966
0
      ecommunity_free(&bgp->vpn_policy[afi].rtlist[dir]);
3967
0
    dir = BGP_VPN_POLICY_DIR_TOVPN;
3968
0
    if (bgp->vpn_policy[afi].rtlist[dir])
3969
0
      ecommunity_free(&bgp->vpn_policy[afi].rtlist[dir]);
3970
0
    if (bgp->vpn_policy[afi].tovpn_rd_pretty)
3971
0
      XFREE(MTYPE_BGP, bgp->vpn_policy[afi].tovpn_rd_pretty);
3972
0
    if (bgp->vpn_policy[afi].tovpn_sid_locator != NULL)
3973
0
      srv6_locator_chunk_free(
3974
0
        &bgp->vpn_policy[afi].tovpn_sid_locator);
3975
0
    if (bgp->vpn_policy[afi].tovpn_zebra_vrf_sid_last_sent != NULL)
3976
0
      XFREE(MTYPE_BGP_SRV6_SID,
3977
0
            bgp->vpn_policy[afi]
3978
0
              .tovpn_zebra_vrf_sid_last_sent);
3979
0
    if (bgp->vpn_policy[afi].tovpn_sid != NULL) {
3980
0
      sid_unregister(bgp, bgp->vpn_policy[afi].tovpn_sid);
3981
0
      XFREE(MTYPE_BGP_SRV6_SID,
3982
0
            bgp->vpn_policy[afi].tovpn_sid);
3983
0
    }
3984
0
  }
3985
3986
0
  bgp_srv6_cleanup(bgp);
3987
0
  bgp_confederation_id_unset(bgp);
3988
3989
0
  XFREE(MTYPE_BGP, bgp->as_pretty);
3990
0
  XFREE(MTYPE_BGP, bgp->name);
3991
0
  XFREE(MTYPE_BGP, bgp->name_pretty);
3992
0
  XFREE(MTYPE_BGP, bgp->snmp_stats);
3993
3994
0
  XFREE(MTYPE_BGP, bgp);
3995
0
}
3996
3997
struct peer *peer_lookup_by_conf_if(struct bgp *bgp, const char *conf_if)
3998
0
{
3999
0
  struct peer *peer;
4000
0
  struct listnode *node, *nnode;
4001
4002
0
  if (!conf_if)
4003
0
    return NULL;
4004
4005
0
  if (bgp != NULL) {
4006
0
    for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer))
4007
0
      if (peer->conf_if && !strcmp(peer->conf_if, conf_if)
4008
0
          && !CHECK_FLAG(peer->sflags,
4009
0
             PEER_STATUS_ACCEPT_PEER))
4010
0
        return peer;
4011
0
  } else if (bm->bgp != NULL) {
4012
0
    struct listnode *bgpnode, *nbgpnode;
4013
4014
0
    for (ALL_LIST_ELEMENTS(bm->bgp, bgpnode, nbgpnode, bgp))
4015
0
      for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer))
4016
0
        if (peer->conf_if
4017
0
            && !strcmp(peer->conf_if, conf_if)
4018
0
            && !CHECK_FLAG(peer->sflags,
4019
0
               PEER_STATUS_ACCEPT_PEER))
4020
0
          return peer;
4021
0
  }
4022
0
  return NULL;
4023
0
}
4024
4025
struct peer *peer_lookup_by_hostname(struct bgp *bgp, const char *hostname)
4026
0
{
4027
0
  struct peer *peer;
4028
0
  struct listnode *node, *nnode;
4029
4030
0
  if (!hostname)
4031
0
    return NULL;
4032
4033
0
  if (bgp != NULL) {
4034
0
    for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer))
4035
0
      if (peer->hostname && !strcmp(peer->hostname, hostname)
4036
0
          && !CHECK_FLAG(peer->sflags,
4037
0
             PEER_STATUS_ACCEPT_PEER))
4038
0
        return peer;
4039
0
  } else if (bm->bgp != NULL) {
4040
0
    struct listnode *bgpnode, *nbgpnode;
4041
4042
0
    for (ALL_LIST_ELEMENTS(bm->bgp, bgpnode, nbgpnode, bgp))
4043
0
      for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer))
4044
0
        if (peer->hostname
4045
0
            && !strcmp(peer->hostname, hostname)
4046
0
            && !CHECK_FLAG(peer->sflags,
4047
0
               PEER_STATUS_ACCEPT_PEER))
4048
0
          return peer;
4049
0
  }
4050
0
  return NULL;
4051
0
}
4052
4053
struct peer *peer_lookup(struct bgp *bgp, union sockunion *su)
4054
0
{
4055
0
  struct peer *peer = NULL;
4056
0
  struct peer tmp_peer;
4057
4058
0
  memset(&tmp_peer, 0, sizeof(struct peer));
4059
4060
  /*
4061
   * We do not want to find the doppelganger peer so search for the peer
4062
   * in
4063
   * the hash that has PEER_FLAG_CONFIG_NODE
4064
   */
4065
0
  SET_FLAG(tmp_peer.flags, PEER_FLAG_CONFIG_NODE);
4066
4067
0
  tmp_peer.su = *su;
4068
4069
0
  if (bgp != NULL) {
4070
0
    peer = hash_lookup(bgp->peerhash, &tmp_peer);
4071
0
  } else if (bm->bgp != NULL) {
4072
0
    struct listnode *bgpnode, *nbgpnode;
4073
4074
0
    for (ALL_LIST_ELEMENTS(bm->bgp, bgpnode, nbgpnode, bgp)) {
4075
0
      peer = hash_lookup(bgp->peerhash, &tmp_peer);
4076
0
      if (peer)
4077
0
        break;
4078
0
    }
4079
0
  }
4080
4081
0
  return peer;
4082
0
}
4083
4084
struct peer *peer_create_bind_dynamic_neighbor(struct bgp *bgp,
4085
                 union sockunion *su,
4086
                 struct peer_group *group)
4087
0
{
4088
0
  struct peer *peer;
4089
0
  afi_t afi;
4090
0
  safi_t safi;
4091
4092
  /* Create peer first; we've already checked group config is valid. */
4093
0
  peer = peer_create(su, NULL, bgp, bgp->as, group->conf->as,
4094
0
         group->conf->as_type, group, true, NULL);
4095
0
  if (!peer)
4096
0
    return NULL;
4097
4098
  /* Link to group */
4099
0
  peer = peer_lock(peer);
4100
0
  listnode_add(group->peer, peer);
4101
4102
0
  peer_group2peer_config_copy(group, peer);
4103
4104
  /*
4105
   * Bind peer for all AFs configured for the group. We don't call
4106
   * peer_group_bind as that is sub-optimal and does some stuff we don't
4107
   * want.
4108
   */
4109
0
  FOREACH_AFI_SAFI (afi, safi) {
4110
0
    if (!group->conf->afc[afi][safi])
4111
0
      continue;
4112
0
    peer->afc[afi][safi] = 1;
4113
4114
0
    if (!peer_af_find(peer, afi, safi))
4115
0
      peer_af_create(peer, afi, safi);
4116
4117
0
    peer_group2peer_config_copy_af(group, peer, afi, safi);
4118
0
  }
4119
4120
  /* Mark as dynamic, but also as a "config node" for other things to
4121
   * work. */
4122
0
  SET_FLAG(peer->flags, PEER_FLAG_DYNAMIC_NEIGHBOR);
4123
4124
0
  return peer;
4125
0
}
4126
4127
struct prefix *
4128
peer_group_lookup_dynamic_neighbor_range(struct peer_group *group,
4129
           struct prefix *prefix)
4130
0
{
4131
0
  struct listnode *node, *nnode;
4132
0
  struct prefix *range;
4133
0
  afi_t afi;
4134
4135
0
  afi = family2afi(prefix->family);
4136
4137
0
  if (group->listen_range[afi])
4138
0
    for (ALL_LIST_ELEMENTS(group->listen_range[afi], node, nnode,
4139
0
               range))
4140
0
      if (prefix_match(range, prefix))
4141
0
        return range;
4142
4143
0
  return NULL;
4144
0
}
4145
4146
struct peer_group *
4147
peer_group_lookup_dynamic_neighbor(struct bgp *bgp, struct prefix *prefix,
4148
           struct prefix **listen_range)
4149
0
{
4150
0
  struct prefix *range = NULL;
4151
0
  struct peer_group *group = NULL;
4152
0
  struct listnode *node, *nnode;
4153
4154
0
  *listen_range = NULL;
4155
0
  if (bgp != NULL) {
4156
0
    for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group))
4157
0
      if ((range = peer_group_lookup_dynamic_neighbor_range(
4158
0
             group, prefix)))
4159
0
        break;
4160
0
  } else if (bm->bgp != NULL) {
4161
0
    struct listnode *bgpnode, *nbgpnode;
4162
4163
0
    for (ALL_LIST_ELEMENTS(bm->bgp, bgpnode, nbgpnode, bgp))
4164
0
      for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group))
4165
0
        if ((range = peer_group_lookup_dynamic_neighbor_range(
4166
0
               group, prefix)))
4167
0
          goto found_range;
4168
0
  }
4169
4170
0
found_range:
4171
0
  *listen_range = range;
4172
0
  return (group && range) ? group : NULL;
4173
0
}
4174
4175
struct peer *peer_lookup_dynamic_neighbor(struct bgp *bgp, union sockunion *su)
4176
0
{
4177
0
  struct peer_group *group;
4178
0
  struct bgp *gbgp;
4179
0
  struct peer *peer;
4180
0
  struct prefix prefix;
4181
0
  struct prefix *listen_range;
4182
0
  int dncount;
4183
4184
0
  if (!sockunion2hostprefix(su, &prefix))
4185
0
    return NULL;
4186
4187
  /* See if incoming connection matches a configured listen range. */
4188
0
  group = peer_group_lookup_dynamic_neighbor(bgp, &prefix, &listen_range);
4189
4190
0
  if (!group)
4191
0
    return NULL;
4192
4193
4194
0
  gbgp = group->bgp;
4195
4196
0
  if (!gbgp)
4197
0
    return NULL;
4198
4199
0
  if (bgp_debug_neighbor_events(NULL))
4200
0
    zlog_debug(
4201
0
      "Dynamic Neighbor %pFX matches group %s listen range %pFX",
4202
0
      &prefix, group->name, listen_range);
4203
4204
  /* Are we within the listen limit? */
4205
0
  dncount = gbgp->dynamic_neighbors_count;
4206
4207
0
  if (dncount >= gbgp->dynamic_neighbors_limit) {
4208
0
    if (bgp_debug_neighbor_events(NULL))
4209
0
      zlog_debug(
4210
0
        "Dynamic Neighbor %pFX rejected - at limit %d",
4211
0
        &prefix, gbgp->dynamic_neighbors_limit);
4212
0
    return NULL;
4213
0
  }
4214
4215
  /* Ensure group is not disabled. */
4216
0
  if (CHECK_FLAG(group->conf->flags, PEER_FLAG_SHUTDOWN)) {
4217
0
    if (bgp_debug_neighbor_events(NULL))
4218
0
      zlog_debug(
4219
0
        "Dynamic Neighbor %pFX rejected - group %s disabled",
4220
0
        &prefix, group->name);
4221
0
    return NULL;
4222
0
  }
4223
4224
  /* Check that at least one AF is activated for the group. */
4225
0
  if (!peer_group_af_configured(group)) {
4226
0
    if (bgp_debug_neighbor_events(NULL))
4227
0
      zlog_debug(
4228
0
        "Dynamic Neighbor %pFX rejected - no AF activated for group %s",
4229
0
        &prefix, group->name);
4230
0
    return NULL;
4231
0
  }
4232
4233
  /* Create dynamic peer and bind to associated group. */
4234
0
  peer = peer_create_bind_dynamic_neighbor(gbgp, su, group);
4235
0
  assert(peer);
4236
4237
0
  gbgp->dynamic_neighbors_count = ++dncount;
4238
4239
0
  if (bgp_debug_neighbor_events(peer))
4240
0
    zlog_debug("%s Dynamic Neighbor added, group %s count %d",
4241
0
         peer->host, group->name, dncount);
4242
4243
0
  return peer;
4244
0
}
4245
4246
static void peer_drop_dynamic_neighbor(struct peer *peer)
4247
0
{
4248
0
  int dncount = -1;
4249
0
  if (peer->group->bgp) {
4250
0
    dncount = peer->group->bgp->dynamic_neighbors_count;
4251
0
    if (dncount)
4252
0
      peer->group->bgp->dynamic_neighbors_count = --dncount;
4253
0
  }
4254
0
  if (bgp_debug_neighbor_events(peer))
4255
0
    zlog_debug("%s dropped from group %s, count %d", peer->host,
4256
0
         peer->group->name, dncount);
4257
0
}
4258
4259
bool bgp_path_attribute_discard(struct peer *peer, char *buf, size_t size)
4260
0
{
4261
0
  if (!buf)
4262
0
    return false;
4263
4264
0
  buf[0] = '\0';
4265
4266
0
  for (unsigned int i = 0; i < BGP_ATTR_MAX; i++) {
4267
0
    if (peer->discard_attrs[i])
4268
0
      snprintf(buf + strlen(buf), size - strlen(buf), "%s%d",
4269
0
         (strlen(buf) > 0) ? " " : "", i);
4270
0
  }
4271
4272
0
  if (strlen(buf) > 0)
4273
0
    return true;
4274
4275
0
  return false;
4276
0
}
4277
4278
bool bgp_path_attribute_treat_as_withdraw(struct peer *peer, char *buf,
4279
            size_t size)
4280
0
{
4281
0
  if (!buf)
4282
0
    return false;
4283
4284
0
  buf[0] = '\0';
4285
4286
0
  for (unsigned int i = 0; i < BGP_ATTR_MAX; i++) {
4287
0
    if (peer->withdraw_attrs[i])
4288
0
      snprintf(buf + strlen(buf), size - strlen(buf), "%s%d",
4289
0
         (strlen(buf) > 0) ? " " : "", i);
4290
0
  }
4291
4292
0
  if (strlen(buf) > 0)
4293
0
    return true;
4294
4295
0
  return false;
4296
0
}
4297
4298
/* If peer is configured at least one address family return 1. */
4299
bool peer_active(struct peer *peer)
4300
4
{
4301
4
  if (BGP_PEER_SU_UNSPEC(peer))
4302
0
    return false;
4303
4
  if (peer->afc[AFI_IP][SAFI_UNICAST] || peer->afc[AFI_IP][SAFI_MULTICAST]
4304
4
      || peer->afc[AFI_IP][SAFI_LABELED_UNICAST]
4305
4
      || peer->afc[AFI_IP][SAFI_MPLS_VPN] || peer->afc[AFI_IP][SAFI_ENCAP]
4306
4
      || peer->afc[AFI_IP][SAFI_FLOWSPEC]
4307
4
      || peer->afc[AFI_IP6][SAFI_UNICAST]
4308
4
      || peer->afc[AFI_IP6][SAFI_MULTICAST]
4309
4
      || peer->afc[AFI_IP6][SAFI_LABELED_UNICAST]
4310
4
      || peer->afc[AFI_IP6][SAFI_MPLS_VPN]
4311
4
      || peer->afc[AFI_IP6][SAFI_ENCAP]
4312
4
      || peer->afc[AFI_IP6][SAFI_FLOWSPEC]
4313
4
      || peer->afc[AFI_L2VPN][SAFI_EVPN])
4314
3
    return true;
4315
1
  return false;
4316
4
}
4317
4318
/* If peer is negotiated at least one address family return 1. */
4319
bool peer_active_nego(struct peer *peer)
4320
26
{
4321
26
  if (peer->afc_nego[AFI_IP][SAFI_UNICAST]
4322
26
      || peer->afc_nego[AFI_IP][SAFI_MULTICAST]
4323
26
      || peer->afc_nego[AFI_IP][SAFI_LABELED_UNICAST]
4324
26
      || peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
4325
26
      || peer->afc_nego[AFI_IP][SAFI_ENCAP]
4326
26
      || peer->afc_nego[AFI_IP][SAFI_FLOWSPEC]
4327
26
      || peer->afc_nego[AFI_IP6][SAFI_UNICAST]
4328
26
      || peer->afc_nego[AFI_IP6][SAFI_MULTICAST]
4329
26
      || peer->afc_nego[AFI_IP6][SAFI_LABELED_UNICAST]
4330
26
      || peer->afc_nego[AFI_IP6][SAFI_MPLS_VPN]
4331
26
      || peer->afc_nego[AFI_IP6][SAFI_ENCAP]
4332
26
      || peer->afc_nego[AFI_IP6][SAFI_FLOWSPEC]
4333
26
      || peer->afc_nego[AFI_L2VPN][SAFI_EVPN])
4334
26
    return true;
4335
0
  return false;
4336
26
}
4337
4338
/* If peer received at least one address family MP, return true */
4339
bool peer_afc_received(struct peer *peer)
4340
0
{
4341
0
  afi_t afi;
4342
0
  safi_t safi;
4343
4344
0
  FOREACH_AFI_SAFI (afi, safi)
4345
0
    if (peer->afc_recv[afi][safi])
4346
0
      return true;
4347
4348
0
  return false;
4349
0
}
4350
4351
/* If peer advertised at least one address family MP, return true */
4352
bool peer_afc_advertised(struct peer *peer)
4353
0
{
4354
0
  afi_t afi;
4355
0
  safi_t safi;
4356
4357
0
  FOREACH_AFI_SAFI (afi, safi)
4358
0
    if (peer->afc_adv[afi][safi])
4359
0
      return true;
4360
4361
0
  return false;
4362
0
}
4363
4364
void peer_change_action(struct peer *peer, afi_t afi, safi_t safi,
4365
             enum peer_change_type type)
4366
0
{
4367
0
  struct peer_af *paf;
4368
4369
0
  if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
4370
0
    return;
4371
4372
0
  if (!peer_established(peer))
4373
0
    return;
4374
4375
0
  if (type == peer_change_reset) {
4376
    /* If we're resetting session, we've to delete both peer struct
4377
     */
4378
0
    if ((peer->doppelganger)
4379
0
        && (peer->doppelganger->status != Deleted)
4380
0
        && (!CHECK_FLAG(peer->doppelganger->flags,
4381
0
            PEER_FLAG_CONFIG_NODE)))
4382
0
      peer_delete(peer->doppelganger);
4383
4384
0
    bgp_notify_send(peer, BGP_NOTIFY_CEASE,
4385
0
        BGP_NOTIFY_CEASE_CONFIG_CHANGE);
4386
0
  } else if (type == peer_change_reset_in) {
4387
0
    if (CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_OLD_RCV)
4388
0
        || CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_NEW_RCV))
4389
0
      bgp_route_refresh_send(peer, afi, safi, 0, 0, 0,
4390
0
                 BGP_ROUTE_REFRESH_NORMAL);
4391
0
    else {
4392
0
      if ((peer->doppelganger)
4393
0
          && (peer->doppelganger->status != Deleted)
4394
0
          && (!CHECK_FLAG(peer->doppelganger->flags,
4395
0
              PEER_FLAG_CONFIG_NODE)))
4396
0
        peer_delete(peer->doppelganger);
4397
4398
0
      bgp_notify_send(peer, BGP_NOTIFY_CEASE,
4399
0
          BGP_NOTIFY_CEASE_CONFIG_CHANGE);
4400
0
    }
4401
0
  } else if (type == peer_change_reset_out) {
4402
0
    paf = peer_af_find(peer, afi, safi);
4403
0
    if (paf && paf->subgroup)
4404
0
      SET_FLAG(paf->subgroup->sflags,
4405
0
         SUBGRP_STATUS_FORCE_UPDATES);
4406
4407
0
    update_group_adjust_peer(paf);
4408
0
    bgp_announce_route(peer, afi, safi, false);
4409
0
  }
4410
0
}
4411
4412
struct peer_flag_action {
4413
  /* Peer's flag.  */
4414
  uint64_t flag;
4415
4416
  /* This flag can be set for peer-group member.  */
4417
  uint8_t not_for_member;
4418
4419
  /* Action when the flag is changed.  */
4420
  enum peer_change_type type;
4421
};
4422
4423
static const struct peer_flag_action peer_flag_action_list[] = {
4424
  {PEER_FLAG_PASSIVE, 0, peer_change_reset},
4425
  {PEER_FLAG_SHUTDOWN, 0, peer_change_reset},
4426
  {PEER_FLAG_RTT_SHUTDOWN, 0, peer_change_none},
4427
  {PEER_FLAG_DONT_CAPABILITY, 0, peer_change_none},
4428
  {PEER_FLAG_OVERRIDE_CAPABILITY, 0, peer_change_none},
4429
  {PEER_FLAG_STRICT_CAP_MATCH, 0, peer_change_none},
4430
  {PEER_FLAG_DYNAMIC_CAPABILITY, 0, peer_change_reset},
4431
  {PEER_FLAG_DISABLE_CONNECTED_CHECK, 0, peer_change_reset},
4432
  {PEER_FLAG_CAPABILITY_ENHE, 0, peer_change_reset},
4433
  {PEER_FLAG_ENFORCE_FIRST_AS, 0, peer_change_reset_in},
4434
  {PEER_FLAG_IFPEER_V6ONLY, 0, peer_change_reset},
4435
  {PEER_FLAG_ROUTEADV, 0, peer_change_none},
4436
  {PEER_FLAG_TIMER, 0, peer_change_none},
4437
  {PEER_FLAG_TIMER_CONNECT, 0, peer_change_none},
4438
  {PEER_FLAG_TIMER_DELAYOPEN, 0, peer_change_none},
4439
  {PEER_FLAG_PASSWORD, 0, peer_change_none},
4440
  {PEER_FLAG_LOCAL_AS, 0, peer_change_reset},
4441
  {PEER_FLAG_LOCAL_AS_NO_PREPEND, 0, peer_change_reset},
4442
  {PEER_FLAG_LOCAL_AS_REPLACE_AS, 0, peer_change_reset},
4443
  {PEER_FLAG_UPDATE_SOURCE, 0, peer_change_none},
4444
  {PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE, 0, peer_change_none},
4445
  {PEER_FLAG_EXTENDED_OPT_PARAMS, 0, peer_change_reset},
4446
  {PEER_FLAG_ROLE_STRICT_MODE, 0, peer_change_reset},
4447
  {PEER_FLAG_ROLE, 0, peer_change_reset},
4448
  {PEER_FLAG_PORT, 0, peer_change_reset},
4449
  {PEER_FLAG_AIGP, 0, peer_change_none},
4450
  {PEER_FLAG_GRACEFUL_SHUTDOWN, 0, peer_change_none},
4451
  {PEER_FLAG_CAPABILITY_SOFT_VERSION, 0, peer_change_reset},
4452
  {0, 0, 0}};
4453
4454
static const struct peer_flag_action peer_af_flag_action_list[] = {
4455
  {PEER_FLAG_SEND_COMMUNITY, 1, peer_change_reset_out},
4456
  {PEER_FLAG_SEND_EXT_COMMUNITY, 1, peer_change_reset_out},
4457
  {PEER_FLAG_SEND_LARGE_COMMUNITY, 1, peer_change_reset_out},
4458
  {PEER_FLAG_NEXTHOP_SELF, 1, peer_change_reset_out},
4459
  {PEER_FLAG_REFLECTOR_CLIENT, 1, peer_change_reset},
4460
  {PEER_FLAG_RSERVER_CLIENT, 1, peer_change_reset},
4461
  {PEER_FLAG_SOFT_RECONFIG, 0, peer_change_reset_in},
4462
  {PEER_FLAG_AS_PATH_UNCHANGED, 1, peer_change_reset_out},
4463
  {PEER_FLAG_NEXTHOP_UNCHANGED, 1, peer_change_reset_out},
4464
  {PEER_FLAG_MED_UNCHANGED, 1, peer_change_reset_out},
4465
  {PEER_FLAG_DEFAULT_ORIGINATE, 0, peer_change_none},
4466
  {PEER_FLAG_REMOVE_PRIVATE_AS, 1, peer_change_reset_out},
4467
  {PEER_FLAG_ALLOWAS_IN, 0, peer_change_reset_in},
4468
  {PEER_FLAG_ALLOWAS_IN_ORIGIN, 0, peer_change_reset_in},
4469
  {PEER_FLAG_ORF_PREFIX_SM, 1, peer_change_reset},
4470
  {PEER_FLAG_ORF_PREFIX_RM, 1, peer_change_reset},
4471
  {PEER_FLAG_MAX_PREFIX, 0, peer_change_none},
4472
  {PEER_FLAG_MAX_PREFIX_WARNING, 0, peer_change_none},
4473
  {PEER_FLAG_MAX_PREFIX_FORCE, 0, peer_change_none},
4474
  {PEER_FLAG_MAX_PREFIX_OUT, 0, peer_change_none},
4475
  {PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED, 0, peer_change_reset_out},
4476
  {PEER_FLAG_FORCE_NEXTHOP_SELF, 1, peer_change_reset_out},
4477
  {PEER_FLAG_REMOVE_PRIVATE_AS_ALL, 1, peer_change_reset_out},
4478
  {PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE, 1, peer_change_reset_out},
4479
  {PEER_FLAG_AS_OVERRIDE, 1, peer_change_reset_out},
4480
  {PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE, 1, peer_change_reset_out},
4481
  {PEER_FLAG_WEIGHT, 0, peer_change_reset_in},
4482
  {PEER_FLAG_DISABLE_ADDPATH_RX, 0, peer_change_reset},
4483
  {PEER_FLAG_SOO, 0, peer_change_reset},
4484
  {PEER_FLAG_ACCEPT_OWN, 0, peer_change_reset},
4485
  {0, 0, 0}};
4486
4487
/* Proper action set. */
4488
static int peer_flag_action_set(const struct peer_flag_action *action_list,
4489
        int size, struct peer_flag_action *action,
4490
        uint64_t flag)
4491
0
{
4492
0
  int i;
4493
0
  int found = 0;
4494
0
  int reset_in = 0;
4495
0
  int reset_out = 0;
4496
0
  const struct peer_flag_action *match = NULL;
4497
4498
  /* Check peer's frag action.  */
4499
0
  for (i = 0; i < size; i++) {
4500
0
    match = &action_list[i];
4501
4502
0
    if (match->flag == 0)
4503
0
      break;
4504
4505
0
    if (match->flag & flag) {
4506
0
      found = 1;
4507
4508
0
      if (match->type == peer_change_reset_in)
4509
0
        reset_in = 1;
4510
0
      if (match->type == peer_change_reset_out)
4511
0
        reset_out = 1;
4512
0
      if (match->type == peer_change_reset) {
4513
0
        reset_in = 1;
4514
0
        reset_out = 1;
4515
0
      }
4516
0
      if (match->not_for_member)
4517
0
        action->not_for_member = 1;
4518
0
    }
4519
0
  }
4520
4521
  /* Set peer clear type.  */
4522
0
  if (reset_in && reset_out)
4523
0
    action->type = peer_change_reset;
4524
0
  else if (reset_in)
4525
0
    action->type = peer_change_reset_in;
4526
0
  else if (reset_out)
4527
0
    action->type = peer_change_reset_out;
4528
0
  else
4529
0
    action->type = peer_change_none;
4530
4531
0
  return found;
4532
0
}
4533
4534
static void peer_flag_modify_action(struct peer *peer, uint64_t flag)
4535
0
{
4536
0
  if (flag == PEER_FLAG_SHUTDOWN) {
4537
0
    if (CHECK_FLAG(peer->flags, flag)) {
4538
0
      if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT))
4539
0
        peer_nsf_stop(peer);
4540
4541
0
      UNSET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
4542
4543
0
      if (peer->t_pmax_restart) {
4544
0
        EVENT_OFF(peer->t_pmax_restart);
4545
0
        if (bgp_debug_neighbor_events(peer))
4546
0
          zlog_debug(
4547
0
            "%pBP Maximum-prefix restart timer canceled",
4548
0
            peer);
4549
0
      }
4550
4551
0
      if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
4552
0
        char *msg = peer->tx_shutdown_message;
4553
0
        size_t msglen;
4554
0
        uint8_t msgbuf[BGP_ADMIN_SHUTDOWN_MSG_LEN + 1];
4555
4556
0
        if (!msg && peer_group_active(peer))
4557
0
          msg = peer->group->conf
4558
0
                  ->tx_shutdown_message;
4559
0
        msglen = msg ? strlen(msg) : 0;
4560
0
        if (msglen > BGP_ADMIN_SHUTDOWN_MSG_LEN)
4561
0
          msglen = BGP_ADMIN_SHUTDOWN_MSG_LEN;
4562
4563
0
        if (msglen) {
4564
0
          msgbuf[0] = msglen;
4565
0
          memcpy(msgbuf + 1, msg, msglen);
4566
4567
0
          bgp_notify_send_with_data(
4568
0
            peer, BGP_NOTIFY_CEASE,
4569
0
            BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN,
4570
0
            msgbuf, msglen + 1);
4571
0
        } else
4572
0
          bgp_notify_send(
4573
0
            peer, BGP_NOTIFY_CEASE,
4574
0
            BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
4575
0
      } else
4576
0
        bgp_session_reset(peer);
4577
0
    } else {
4578
0
      peer->v_start = BGP_INIT_START_TIMER;
4579
0
      BGP_EVENT_ADD(peer, BGP_Stop);
4580
0
    }
4581
0
  } else if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
4582
0
    if (flag == PEER_FLAG_DYNAMIC_CAPABILITY)
4583
0
      peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
4584
0
    else if (flag == PEER_FLAG_PASSIVE)
4585
0
      peer->last_reset = PEER_DOWN_PASSIVE_CHANGE;
4586
0
    else if (flag == PEER_FLAG_DISABLE_CONNECTED_CHECK)
4587
0
      peer->last_reset = PEER_DOWN_MULTIHOP_CHANGE;
4588
4589
0
    bgp_notify_send(peer, BGP_NOTIFY_CEASE,
4590
0
        BGP_NOTIFY_CEASE_CONFIG_CHANGE);
4591
0
  } else
4592
0
    bgp_session_reset(peer);
4593
0
}
4594
4595
/* Enable global administrative shutdown of all peers of BGP instance */
4596
void bgp_shutdown_enable(struct bgp *bgp, const char *msg)
4597
0
{
4598
0
  struct peer *peer;
4599
0
  struct listnode *node;
4600
  /* length(1) + message(N) */
4601
0
  uint8_t data[BGP_ADMIN_SHUTDOWN_MSG_LEN + 1];
4602
4603
  /* do nothing if already shut down */
4604
0
  if (CHECK_FLAG(bgp->flags, BGP_FLAG_SHUTDOWN))
4605
0
    return;
4606
4607
  /* informational log message */
4608
0
  zlog_info("Enabled administrative shutdown on BGP instance AS %u",
4609
0
      bgp->as);
4610
4611
  /* iterate through peers of BGP instance */
4612
0
  for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer)) {
4613
    /* continue, if peer is already in administrative shutdown. */
4614
0
    if (CHECK_FLAG(peer->flags, PEER_FLAG_SHUTDOWN))
4615
0
      continue;
4616
4617
    /* send a RFC 4486 notification message if necessary */
4618
0
    if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
4619
0
      if (msg) {
4620
0
        size_t datalen = strlen(msg);
4621
4622
0
        if (datalen > BGP_ADMIN_SHUTDOWN_MSG_LEN)
4623
0
          datalen = BGP_ADMIN_SHUTDOWN_MSG_LEN;
4624
4625
0
        data[0] = datalen;
4626
0
        memcpy(data + 1, msg, datalen);
4627
4628
0
        bgp_notify_send_with_data(
4629
0
          peer, BGP_NOTIFY_CEASE,
4630
0
          BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN, data,
4631
0
          datalen + 1);
4632
0
      } else {
4633
0
        bgp_notify_send(
4634
0
          peer, BGP_NOTIFY_CEASE,
4635
0
          BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
4636
0
      }
4637
0
    }
4638
4639
    /* reset start timer to initial value */
4640
0
    peer->v_start = BGP_INIT_START_TIMER;
4641
4642
    /* trigger a RFC 4271 ManualStop event */
4643
0
    BGP_EVENT_ADD(peer, BGP_Stop);
4644
0
  }
4645
4646
  /* set the BGP instances shutdown flag */
4647
0
  SET_FLAG(bgp->flags, BGP_FLAG_SHUTDOWN);
4648
0
}
4649
4650
/* Disable global administrative shutdown of all peers of BGP instance */
4651
void bgp_shutdown_disable(struct bgp *bgp)
4652
0
{
4653
0
  const struct listnode *node;
4654
0
  struct peer *peer;
4655
4656
  /* do nothing if not shut down. */
4657
0
  if (!CHECK_FLAG(bgp->flags, BGP_FLAG_SHUTDOWN))
4658
0
    return;
4659
4660
  /* informational log message */
4661
0
  zlog_info("Disabled administrative shutdown on BGP instance AS %u",
4662
0
      bgp->as);
4663
4664
  /* clear the BGP instances shutdown flag */
4665
0
  UNSET_FLAG(bgp->flags, BGP_FLAG_SHUTDOWN);
4666
4667
0
  for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer))
4668
0
    bgp_timer_set(peer);
4669
0
}
4670
4671
/* Change specified peer flag. */
4672
static int peer_flag_modify(struct peer *peer, uint64_t flag, int set)
4673
0
{
4674
0
  int found;
4675
0
  int size;
4676
0
  bool invert, member_invert;
4677
0
  struct peer *member;
4678
0
  struct listnode *node, *nnode;
4679
0
  struct peer_flag_action action;
4680
4681
0
  memset(&action, 0, sizeof(struct peer_flag_action));
4682
0
  size = sizeof(peer_flag_action_list) / sizeof(struct peer_flag_action);
4683
4684
0
  invert = CHECK_FLAG(peer->flags_invert, flag);
4685
0
  found = peer_flag_action_set(peer_flag_action_list, size, &action,
4686
0
             flag);
4687
4688
  /* Abort if no flag action exists. */
4689
0
  if (!found)
4690
0
    return BGP_ERR_INVALID_FLAG;
4691
4692
  /* Check for flag conflict: STRICT_CAP_MATCH && OVERRIDE_CAPABILITY */
4693
0
  if (set && CHECK_FLAG(peer->flags | flag, PEER_FLAG_STRICT_CAP_MATCH)
4694
0
      && CHECK_FLAG(peer->flags | flag, PEER_FLAG_OVERRIDE_CAPABILITY))
4695
0
    return BGP_ERR_PEER_FLAG_CONFLICT;
4696
4697
  /* Handle flag updates where desired state matches current state. */
4698
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4699
0
    if (set && CHECK_FLAG(peer->flags, flag)) {
4700
0
      COND_FLAG(peer->flags_override, flag, !invert);
4701
0
      return 0;
4702
0
    }
4703
4704
0
    if (!set && !CHECK_FLAG(peer->flags, flag)) {
4705
0
      COND_FLAG(peer->flags_override, flag, invert);
4706
0
      return 0;
4707
0
    }
4708
0
  }
4709
4710
  /* Inherit from peer-group or set/unset flags accordingly. */
4711
0
  if (peer_group_active(peer) && set == invert)
4712
0
    peer_flag_inherit(peer, flag);
4713
0
  else
4714
0
    COND_FLAG(peer->flags, flag, set);
4715
4716
  /* Check if handling a regular peer. */
4717
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4718
    /* Update flag override state accordingly. */
4719
0
    COND_FLAG(peer->flags_override, flag, set != invert);
4720
4721
    /*
4722
     * For the extended next-hop encoding flag we need to turn RAs
4723
     * on if flag is being set, but only turn RAs off if the flag
4724
     * is being unset on this peer and if this peer is a member of a
4725
     * peer-group, the peer-group also doesn't have the flag set.
4726
     */
4727
0
    if (flag == PEER_FLAG_CAPABILITY_ENHE) {
4728
0
      if (set) {
4729
0
        bgp_zebra_initiate_radv(peer->bgp, peer);
4730
0
      } else if (peer_group_active(peer)) {
4731
0
        if (!CHECK_FLAG(peer->group->conf->flags,
4732
0
            flag) &&
4733
0
            !peer->conf_if)
4734
0
          bgp_zebra_terminate_radv(peer->bgp,
4735
0
                 peer);
4736
0
      } else
4737
0
        bgp_zebra_terminate_radv(peer->bgp, peer);
4738
0
    }
4739
4740
    /* Execute flag action on peer. */
4741
0
    if (action.type == peer_change_reset)
4742
0
      peer_flag_modify_action(peer, flag);
4743
4744
    /* Skip peer-group mechanics for regular peers. */
4745
0
    return 0;
4746
0
  }
4747
4748
  /*
4749
   * Update peer-group members, unless they are explicitly overriding
4750
   * peer-group configuration.
4751
   */
4752
0
  for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
4753
    /* Skip peers with overridden configuration. */
4754
0
    if (CHECK_FLAG(member->flags_override, flag))
4755
0
      continue;
4756
4757
    /* Check if only member without group is inverted. */
4758
0
    member_invert =
4759
0
      CHECK_FLAG(member->flags_invert, flag) && !invert;
4760
4761
    /* Skip peers with equivalent configuration. */
4762
0
    if (set != member_invert && CHECK_FLAG(member->flags, flag))
4763
0
      continue;
4764
4765
0
    if (set == member_invert && !CHECK_FLAG(member->flags, flag))
4766
0
      continue;
4767
4768
    /* Update flag on peer-group member. */
4769
0
    COND_FLAG(member->flags, flag, set != member_invert);
4770
4771
0
    if (flag == PEER_FLAG_CAPABILITY_ENHE && !member->conf_if)
4772
0
      set ? bgp_zebra_initiate_radv(member->bgp, member)
4773
0
          : bgp_zebra_terminate_radv(member->bgp, member);
4774
4775
    /* Execute flag action on peer-group member. */
4776
0
    if (action.type == peer_change_reset)
4777
0
      peer_flag_modify_action(member, flag);
4778
0
  }
4779
4780
0
  return 0;
4781
0
}
4782
4783
int peer_flag_set(struct peer *peer, uint64_t flag)
4784
0
{
4785
0
  return peer_flag_modify(peer, flag, 1);
4786
0
}
4787
4788
int peer_flag_unset(struct peer *peer, uint64_t flag)
4789
0
{
4790
0
  return peer_flag_modify(peer, flag, 0);
4791
0
}
4792
4793
static int peer_af_flag_modify(struct peer *peer, afi_t afi, safi_t safi,
4794
             uint64_t flag, bool set)
4795
0
{
4796
0
  int found;
4797
0
  int size;
4798
0
  bool invert, member_invert;
4799
0
  struct peer *member;
4800
0
  struct listnode *node, *nnode;
4801
0
  struct peer_flag_action action;
4802
0
  enum bgp_peer_sort ptype;
4803
4804
0
  memset(&action, 0, sizeof(struct peer_flag_action));
4805
0
  size = sizeof(peer_af_flag_action_list)
4806
0
         / sizeof(struct peer_flag_action);
4807
4808
0
  invert = CHECK_FLAG(peer->af_flags_invert[afi][safi], flag);
4809
0
  found = peer_flag_action_set(peer_af_flag_action_list, size, &action,
4810
0
             flag);
4811
4812
  /* Abort if flag action exists. */
4813
0
  if (!found)
4814
0
    return BGP_ERR_INVALID_FLAG;
4815
4816
0
  ptype = peer_sort(peer);
4817
  /* Special check for reflector client.  */
4818
0
  if (flag & PEER_FLAG_REFLECTOR_CLIENT && ptype != BGP_PEER_IBGP)
4819
0
    return BGP_ERR_NOT_INTERNAL_PEER;
4820
4821
  /* Special check for remove-private-AS.  */
4822
0
  if (flag & PEER_FLAG_REMOVE_PRIVATE_AS && ptype == BGP_PEER_IBGP)
4823
0
    return BGP_ERR_REMOVE_PRIVATE_AS;
4824
4825
  /* as-override is not allowed for IBGP peers */
4826
0
  if (flag & PEER_FLAG_AS_OVERRIDE && ptype == BGP_PEER_IBGP)
4827
0
    return BGP_ERR_AS_OVERRIDE;
4828
4829
  /* Handle flag updates where desired state matches current state. */
4830
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4831
0
    if (set && CHECK_FLAG(peer->af_flags[afi][safi], flag)) {
4832
0
      COND_FLAG(peer->af_flags_override[afi][safi], flag,
4833
0
          !invert);
4834
0
      return 0;
4835
0
    }
4836
4837
0
    if (!set && !CHECK_FLAG(peer->af_flags[afi][safi], flag)) {
4838
0
      COND_FLAG(peer->af_flags_override[afi][safi], flag,
4839
0
          invert);
4840
0
      return 0;
4841
0
    }
4842
0
  }
4843
4844
  /*
4845
   * For EVPN we implicitly set the NEXTHOP_UNCHANGED flag,
4846
   * if we are setting/unsetting flags which conflict with this flag
4847
   * handle accordingly
4848
   */
4849
0
  if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
4850
0
    if (set) {
4851
4852
      /*
4853
       * if we are setting NEXTHOP_SELF, we need to unset the
4854
       * NEXTHOP_UNCHANGED flag
4855
       */
4856
0
      if (CHECK_FLAG(flag, PEER_FLAG_NEXTHOP_SELF) ||
4857
0
          CHECK_FLAG(flag, PEER_FLAG_FORCE_NEXTHOP_SELF))
4858
0
        UNSET_FLAG(peer->af_flags[afi][safi],
4859
0
             PEER_FLAG_NEXTHOP_UNCHANGED);
4860
0
    } else {
4861
4862
      /*
4863
       * if we are unsetting NEXTHOP_SELF, we need to set the
4864
       * NEXTHOP_UNCHANGED flag to reset the defaults for EVPN
4865
       */
4866
0
      if (CHECK_FLAG(flag, PEER_FLAG_NEXTHOP_SELF) ||
4867
0
          CHECK_FLAG(flag, PEER_FLAG_FORCE_NEXTHOP_SELF))
4868
0
        SET_FLAG(peer->af_flags[afi][safi],
4869
0
           PEER_FLAG_NEXTHOP_UNCHANGED);
4870
0
    }
4871
0
  }
4872
4873
  /*
4874
   * If the peer is a route server client let's not
4875
   * muck with the nexthop on the way out the door
4876
   */
4877
0
  if (flag & PEER_FLAG_RSERVER_CLIENT) {
4878
0
    if (set)
4879
0
      SET_FLAG(peer->af_flags[afi][safi],
4880
0
         PEER_FLAG_NEXTHOP_UNCHANGED);
4881
0
    else
4882
0
      UNSET_FLAG(peer->af_flags[afi][safi],
4883
0
           PEER_FLAG_NEXTHOP_UNCHANGED);
4884
0
  }
4885
4886
  /* Inherit from peer-group or set/unset flags accordingly. */
4887
0
  if (peer_group_active(peer) && set == invert)
4888
0
    peer_af_flag_inherit(peer, afi, safi, flag);
4889
0
  else
4890
0
    COND_FLAG(peer->af_flags[afi][safi], flag, set);
4891
4892
  /* Execute action when peer is established.  */
4893
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)
4894
0
      && peer_established(peer)) {
4895
0
    if (!set && flag == PEER_FLAG_SOFT_RECONFIG)
4896
0
      bgp_clear_adj_in(peer, afi, safi);
4897
0
    else {
4898
0
      if (flag == PEER_FLAG_REFLECTOR_CLIENT)
4899
0
        peer->last_reset = PEER_DOWN_RR_CLIENT_CHANGE;
4900
0
      else if (flag == PEER_FLAG_RSERVER_CLIENT)
4901
0
        peer->last_reset = PEER_DOWN_RS_CLIENT_CHANGE;
4902
0
      else if (flag == PEER_FLAG_ORF_PREFIX_SM)
4903
0
        peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
4904
0
      else if (flag == PEER_FLAG_ORF_PREFIX_RM)
4905
0
        peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
4906
4907
0
      peer_change_action(peer, afi, safi, action.type);
4908
0
    }
4909
0
  }
4910
4911
  /* Check if handling a regular peer. */
4912
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4913
0
    COND_FLAG(peer->af_flags_override[afi][safi], flag,
4914
0
        set != invert);
4915
0
  } else {
4916
    /*
4917
     * Update peer-group members, unless they are explicitly
4918
     * overriding peer-group configuration.
4919
     */
4920
0
    for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode,
4921
0
               member)) {
4922
      /* Skip peers with overridden configuration. */
4923
0
      if (CHECK_FLAG(member->af_flags_override[afi][safi],
4924
0
               flag))
4925
0
        continue;
4926
4927
      /* Check if only member without group is inverted. */
4928
0
      member_invert =
4929
0
        CHECK_FLAG(member->af_flags_invert[afi][safi],
4930
0
             flag)
4931
0
        && !invert;
4932
4933
      /* Skip peers with equivalent configuration. */
4934
0
      if (set != member_invert
4935
0
          && CHECK_FLAG(member->af_flags[afi][safi], flag))
4936
0
        continue;
4937
4938
0
      if (set == member_invert
4939
0
          && !CHECK_FLAG(member->af_flags[afi][safi], flag))
4940
0
        continue;
4941
4942
      /* Update flag on peer-group member. */
4943
0
      COND_FLAG(member->af_flags[afi][safi], flag,
4944
0
          set != member_invert);
4945
4946
      /* Execute flag action on peer-group member. */
4947
0
      if (peer_established(member)) {
4948
0
        if (!set && flag == PEER_FLAG_SOFT_RECONFIG)
4949
0
          bgp_clear_adj_in(member, afi, safi);
4950
0
        else {
4951
0
          if (flag == PEER_FLAG_REFLECTOR_CLIENT)
4952
0
            member->last_reset =
4953
0
              PEER_DOWN_RR_CLIENT_CHANGE;
4954
0
          else if (flag
4955
0
             == PEER_FLAG_RSERVER_CLIENT)
4956
0
            member->last_reset =
4957
0
              PEER_DOWN_RS_CLIENT_CHANGE;
4958
0
          else if (flag
4959
0
             == PEER_FLAG_ORF_PREFIX_SM)
4960
0
            member->last_reset =
4961
0
              PEER_DOWN_CAPABILITY_CHANGE;
4962
0
          else if (flag
4963
0
             == PEER_FLAG_ORF_PREFIX_RM)
4964
0
            member->last_reset =
4965
0
              PEER_DOWN_CAPABILITY_CHANGE;
4966
4967
0
          peer_change_action(member, afi, safi,
4968
0
                 action.type);
4969
0
        }
4970
0
      }
4971
0
    }
4972
0
  }
4973
4974
0
  return 0;
4975
0
}
4976
4977
int peer_af_flag_set(struct peer *peer, afi_t afi, safi_t safi, uint64_t flag)
4978
0
{
4979
0
  return peer_af_flag_modify(peer, afi, safi, flag, 1);
4980
0
}
4981
4982
int peer_af_flag_unset(struct peer *peer, afi_t afi, safi_t safi, uint64_t flag)
4983
0
{
4984
0
  return peer_af_flag_modify(peer, afi, safi, flag, 0);
4985
0
}
4986
4987
4988
void peer_tx_shutdown_message_set(struct peer *peer, const char *msg)
4989
0
{
4990
0
  XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG, peer->tx_shutdown_message);
4991
0
  peer->tx_shutdown_message =
4992
0
    msg ? XSTRDUP(MTYPE_PEER_TX_SHUTDOWN_MSG, msg) : NULL;
4993
0
}
4994
4995
void peer_tx_shutdown_message_unset(struct peer *peer)
4996
0
{
4997
0
  XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG, peer->tx_shutdown_message);
4998
0
}
4999
5000
5001
/* EBGP multihop configuration. */
5002
int peer_ebgp_multihop_set(struct peer *peer, int ttl)
5003
0
{
5004
0
  struct peer_group *group;
5005
0
  struct listnode *node, *nnode;
5006
0
  struct peer *peer1;
5007
5008
0
  if (peer->sort == BGP_PEER_IBGP || peer->conf_if)
5009
0
    return 0;
5010
5011
  /* is there anything to do? */
5012
0
  if (peer->ttl == ttl)
5013
0
    return 0;
5014
5015
  /* see comment in peer_ttl_security_hops_set() */
5016
0
  if (ttl != MAXTTL) {
5017
0
    if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5018
0
      group = peer->group;
5019
0
      if (group->conf->gtsm_hops != BGP_GTSM_HOPS_DISABLED)
5020
0
        return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
5021
5022
0
      for (ALL_LIST_ELEMENTS(group->peer, node, nnode,
5023
0
                 peer1)) {
5024
0
        if (peer1->sort == BGP_PEER_IBGP)
5025
0
          continue;
5026
5027
0
        if (peer1->gtsm_hops != BGP_GTSM_HOPS_DISABLED)
5028
0
          return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
5029
0
      }
5030
0
    } else {
5031
0
      if (peer->gtsm_hops != BGP_GTSM_HOPS_DISABLED)
5032
0
        return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
5033
0
    }
5034
0
  }
5035
5036
0
  peer->ttl = ttl;
5037
5038
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5039
0
    if (peer->sort != BGP_PEER_IBGP) {
5040
0
      if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
5041
0
        bgp_notify_send(peer, BGP_NOTIFY_CEASE,
5042
0
            BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5043
0
      else
5044
0
        bgp_session_reset(peer);
5045
5046
      /* Reconfigure BFD peer with new TTL. */
5047
0
      if (peer->bfd_config)
5048
0
        bgp_peer_bfd_update_source(peer);
5049
0
    }
5050
0
  } else {
5051
0
    group = peer->group;
5052
0
    for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
5053
0
      if (peer->sort == BGP_PEER_IBGP)
5054
0
        continue;
5055
5056
0
      peer->ttl = group->conf->ttl;
5057
5058
0
      if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
5059
0
        bgp_notify_send(peer, BGP_NOTIFY_CEASE,
5060
0
            BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5061
0
      else
5062
0
        bgp_session_reset(peer);
5063
5064
      /* Reconfigure BFD peer with new TTL. */
5065
0
      if (peer->bfd_config)
5066
0
        bgp_peer_bfd_update_source(peer);
5067
0
    }
5068
0
  }
5069
0
  return 0;
5070
0
}
5071
5072
int peer_ebgp_multihop_unset(struct peer *peer)
5073
0
{
5074
0
  struct peer_group *group;
5075
0
  struct listnode *node, *nnode;
5076
0
  int ttl;
5077
5078
0
  if (peer->sort == BGP_PEER_IBGP)
5079
0
    return 0;
5080
5081
0
  if (peer->gtsm_hops != BGP_GTSM_HOPS_DISABLED && peer->ttl != MAXTTL)
5082
0
    return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
5083
5084
0
  if (peer_group_active(peer))
5085
0
    ttl = peer->group->conf->ttl;
5086
0
  else
5087
0
    ttl = BGP_DEFAULT_TTL;
5088
5089
0
  if (ttl == peer->ttl)
5090
0
    return 0;
5091
5092
0
  peer->ttl = ttl;
5093
5094
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5095
0
    if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
5096
0
      bgp_notify_send(peer, BGP_NOTIFY_CEASE,
5097
0
          BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5098
0
    else
5099
0
      bgp_session_reset(peer);
5100
5101
    /* Reconfigure BFD peer with new TTL. */
5102
0
    if (peer->bfd_config)
5103
0
      bgp_peer_bfd_update_source(peer);
5104
0
  } else {
5105
0
    group = peer->group;
5106
0
    for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
5107
0
      if (peer->sort == BGP_PEER_IBGP)
5108
0
        continue;
5109
5110
0
      peer->ttl = BGP_DEFAULT_TTL;
5111
5112
0
      if (peer->fd >= 0) {
5113
0
        if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
5114
0
          bgp_notify_send(
5115
0
            peer, BGP_NOTIFY_CEASE,
5116
0
            BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5117
0
        else
5118
0
          bgp_session_reset(peer);
5119
0
      }
5120
5121
      /* Reconfigure BFD peer with new TTL. */
5122
0
      if (peer->bfd_config)
5123
0
        bgp_peer_bfd_update_source(peer);
5124
0
    }
5125
0
  }
5126
0
  return 0;
5127
0
}
5128
5129
/* Set Open Policy Role and check its correctness */
5130
int peer_role_set(struct peer *peer, uint8_t role, bool strict_mode)
5131
0
{
5132
0
  struct peer *member;
5133
0
  struct listnode *node, *nnode;
5134
5135
0
  peer_flag_set(peer, PEER_FLAG_ROLE);
5136
5137
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5138
0
    if (peer->sort != BGP_PEER_EBGP)
5139
0
      return BGP_ERR_INVALID_INTERNAL_ROLE;
5140
5141
0
    if (peer->local_role == role) {
5142
0
      if (CHECK_FLAG(peer->flags,
5143
0
               PEER_FLAG_ROLE_STRICT_MODE) &&
5144
0
          !strict_mode)
5145
        /* TODO: Is session restart needed if it was
5146
         * down?
5147
         */
5148
0
        UNSET_FLAG(peer->flags,
5149
0
             PEER_FLAG_ROLE_STRICT_MODE);
5150
0
      if (!CHECK_FLAG(peer->flags,
5151
0
          PEER_FLAG_ROLE_STRICT_MODE) &&
5152
0
          strict_mode) {
5153
0
        SET_FLAG(peer->flags,
5154
0
           PEER_FLAG_ROLE_STRICT_MODE);
5155
        /* Restart session to throw Role Mismatch
5156
         * Notification
5157
         */
5158
0
        if (peer->remote_role == ROLE_UNDEFINED)
5159
0
          bgp_session_reset(peer);
5160
0
      }
5161
0
    } else {
5162
0
      peer->local_role = role;
5163
0
      if (strict_mode)
5164
0
        SET_FLAG(peer->flags,
5165
0
           PEER_FLAG_ROLE_STRICT_MODE);
5166
0
      else
5167
0
        UNSET_FLAG(peer->flags,
5168
0
             PEER_FLAG_ROLE_STRICT_MODE);
5169
0
      bgp_session_reset(peer);
5170
0
    }
5171
5172
0
    return CMD_SUCCESS;
5173
0
  }
5174
5175
0
  peer->local_role = role;
5176
0
  for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5177
0
    if (member->sort != BGP_PEER_EBGP)
5178
0
      return BGP_ERR_INVALID_INTERNAL_ROLE;
5179
5180
0
    if (member->local_role == role) {
5181
0
      if (CHECK_FLAG(member->flags,
5182
0
               PEER_FLAG_ROLE_STRICT_MODE) &&
5183
0
          !strict_mode)
5184
        /* TODO: Is session restart needed if it was
5185
         * down?
5186
         */
5187
0
        UNSET_FLAG(member->flags,
5188
0
             PEER_FLAG_ROLE_STRICT_MODE);
5189
0
      if (!CHECK_FLAG(member->flags,
5190
0
          PEER_FLAG_ROLE_STRICT_MODE) &&
5191
0
          strict_mode) {
5192
0
        SET_FLAG(peer->flags,
5193
0
           PEER_FLAG_ROLE_STRICT_MODE);
5194
0
        SET_FLAG(member->flags,
5195
0
           PEER_FLAG_ROLE_STRICT_MODE);
5196
        /* Restart session to throw Role Mismatch
5197
         * Notification
5198
         */
5199
0
        if (member->remote_role == ROLE_UNDEFINED)
5200
0
          bgp_session_reset(member);
5201
0
      }
5202
0
    } else {
5203
0
      member->local_role = role;
5204
5205
0
      if (strict_mode) {
5206
0
        SET_FLAG(peer->flags,
5207
0
           PEER_FLAG_ROLE_STRICT_MODE);
5208
0
        SET_FLAG(member->flags,
5209
0
           PEER_FLAG_ROLE_STRICT_MODE);
5210
0
      } else {
5211
0
        UNSET_FLAG(member->flags,
5212
0
             PEER_FLAG_ROLE_STRICT_MODE);
5213
0
      }
5214
0
      bgp_session_reset(member);
5215
0
    }
5216
0
  }
5217
5218
0
  return CMD_SUCCESS;
5219
0
}
5220
5221
int peer_role_unset(struct peer *peer)
5222
0
{
5223
0
  struct peer *member;
5224
0
  struct listnode *node, *nnode;
5225
5226
0
  peer_flag_unset(peer, PEER_FLAG_ROLE);
5227
5228
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
5229
0
    return peer_role_set(peer, ROLE_UNDEFINED, 0);
5230
5231
0
  for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member))
5232
0
    peer_role_set(member, ROLE_UNDEFINED, 0);
5233
5234
0
  return CMD_SUCCESS;
5235
0
}
5236
5237
/* Neighbor description. */
5238
void peer_description_set(struct peer *peer, const char *desc)
5239
0
{
5240
0
  XFREE(MTYPE_PEER_DESC, peer->desc);
5241
5242
0
  peer->desc = XSTRDUP(MTYPE_PEER_DESC, desc);
5243
0
}
5244
5245
void peer_description_unset(struct peer *peer)
5246
0
{
5247
0
  XFREE(MTYPE_PEER_DESC, peer->desc);
5248
0
}
5249
5250
/* Neighbor update-source. */
5251
int peer_update_source_if_set(struct peer *peer, const char *ifname)
5252
0
{
5253
0
  struct peer *member;
5254
0
  struct listnode *node, *nnode;
5255
5256
  /* Set flag and configuration on peer. */
5257
0
  peer_flag_set(peer, PEER_FLAG_UPDATE_SOURCE);
5258
0
  if (peer->update_if) {
5259
0
    if (strcmp(peer->update_if, ifname) == 0)
5260
0
      return 0;
5261
0
    XFREE(MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
5262
0
  }
5263
0
  peer->update_if = XSTRDUP(MTYPE_PEER_UPDATE_SOURCE, ifname);
5264
0
  sockunion_free(peer->update_source);
5265
0
  peer->update_source = NULL;
5266
5267
  /* Check if handling a regular peer. */
5268
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5269
    /* Send notification or reset peer depending on state. */
5270
0
    if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
5271
0
      peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
5272
0
      bgp_notify_send(peer, BGP_NOTIFY_CEASE,
5273
0
          BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5274
0
    } else
5275
0
      bgp_session_reset(peer);
5276
5277
    /* Apply new source configuration to BFD session. */
5278
0
    if (peer->bfd_config)
5279
0
      bgp_peer_bfd_update_source(peer);
5280
5281
    /* Skip peer-group mechanics for regular peers. */
5282
0
    return 0;
5283
0
  }
5284
5285
  /*
5286
   * Set flag and configuration on all peer-group members, unless they are
5287
   * explicitly overriding peer-group configuration.
5288
   */
5289
0
  for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5290
    /* Skip peers with overridden configuration. */
5291
0
    if (CHECK_FLAG(member->flags_override, PEER_FLAG_UPDATE_SOURCE))
5292
0
      continue;
5293
5294
    /* Skip peers with the same configuration. */
5295
0
    if (member->update_if) {
5296
0
      if (strcmp(member->update_if, ifname) == 0)
5297
0
        continue;
5298
0
      XFREE(MTYPE_PEER_UPDATE_SOURCE, member->update_if);
5299
0
    }
5300
5301
    /* Set flag and configuration on peer-group member. */
5302
0
    SET_FLAG(member->flags, PEER_FLAG_UPDATE_SOURCE);
5303
0
    member->update_if = XSTRDUP(MTYPE_PEER_UPDATE_SOURCE, ifname);
5304
0
    sockunion_free(member->update_source);
5305
0
    member->update_source = NULL;
5306
5307
    /* Send notification or reset peer depending on state. */
5308
0
    if (BGP_IS_VALID_STATE_FOR_NOTIF(member->status)) {
5309
0
      member->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
5310
0
      bgp_notify_send(member, BGP_NOTIFY_CEASE,
5311
0
          BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5312
0
    } else
5313
0
      bgp_session_reset(member);
5314
5315
    /* Apply new source configuration to BFD session. */
5316
0
    if (member->bfd_config)
5317
0
      bgp_peer_bfd_update_source(member);
5318
0
  }
5319
5320
0
  return 0;
5321
0
}
5322
5323
void peer_update_source_addr_set(struct peer *peer, const union sockunion *su)
5324
0
{
5325
0
  struct peer *member;
5326
0
  struct listnode *node, *nnode;
5327
5328
  /* Set flag and configuration on peer. */
5329
0
  peer_flag_set(peer, PEER_FLAG_UPDATE_SOURCE);
5330
0
  if (peer->update_source) {
5331
0
    if (sockunion_cmp(peer->update_source, su) == 0)
5332
0
      return;
5333
0
    sockunion_free(peer->update_source);
5334
0
  }
5335
0
  peer->update_source = sockunion_dup(su);
5336
0
  XFREE(MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
5337
5338
  /* Check if handling a regular peer. */
5339
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5340
    /* Send notification or reset peer depending on state. */
5341
0
    if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
5342
0
      peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
5343
0
      bgp_notify_send(peer, BGP_NOTIFY_CEASE,
5344
0
          BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5345
0
    } else
5346
0
      bgp_session_reset(peer);
5347
5348
    /* Apply new source configuration to BFD session. */
5349
0
    if (peer->bfd_config)
5350
0
      bgp_peer_bfd_update_source(peer);
5351
5352
    /* Skip peer-group mechanics for regular peers. */
5353
0
    return;
5354
0
  }
5355
5356
  /*
5357
   * Set flag and configuration on all peer-group members, unless they are
5358
   * explicitly overriding peer-group configuration.
5359
   */
5360
0
  for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5361
    /* Skip peers with overridden configuration. */
5362
0
    if (CHECK_FLAG(member->flags_override, PEER_FLAG_UPDATE_SOURCE))
5363
0
      continue;
5364
5365
    /* Skip peers with the same configuration. */
5366
0
    if (member->update_source) {
5367
0
      if (sockunion_cmp(member->update_source, su) == 0)
5368
0
        continue;
5369
0
      sockunion_free(member->update_source);
5370
0
    }
5371
5372
    /* Set flag and configuration on peer-group member. */
5373
0
    SET_FLAG(member->flags, PEER_FLAG_UPDATE_SOURCE);
5374
0
    member->update_source = sockunion_dup(su);
5375
0
    XFREE(MTYPE_PEER_UPDATE_SOURCE, member->update_if);
5376
5377
    /* Send notification or reset peer depending on state. */
5378
0
    if (BGP_IS_VALID_STATE_FOR_NOTIF(member->status)) {
5379
0
      member->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
5380
0
      bgp_notify_send(member, BGP_NOTIFY_CEASE,
5381
0
          BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5382
0
    } else
5383
0
      bgp_session_reset(member);
5384
5385
    /* Apply new source configuration to BFD session. */
5386
0
    if (member->bfd_config)
5387
0
      bgp_peer_bfd_update_source(member);
5388
0
  }
5389
0
}
5390
5391
void peer_update_source_unset(struct peer *peer)
5392
0
{
5393
0
  struct peer *member;
5394
0
  struct listnode *node, *nnode;
5395
5396
0
  if (!CHECK_FLAG(peer->flags, PEER_FLAG_UPDATE_SOURCE))
5397
0
    return;
5398
5399
  /* Inherit configuration from peer-group if peer is member. */
5400
0
  if (peer_group_active(peer)) {
5401
0
    peer_flag_inherit(peer, PEER_FLAG_UPDATE_SOURCE);
5402
0
    PEER_SU_ATTR_INHERIT(peer, peer->group, update_source);
5403
0
    PEER_STR_ATTR_INHERIT(peer, peer->group, update_if,
5404
0
              MTYPE_PEER_UPDATE_SOURCE);
5405
0
  } else {
5406
    /* Otherwise remove flag and configuration from peer. */
5407
0
    peer_flag_unset(peer, PEER_FLAG_UPDATE_SOURCE);
5408
0
    sockunion_free(peer->update_source);
5409
0
    peer->update_source = NULL;
5410
0
    XFREE(MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
5411
0
  }
5412
5413
  /* Check if handling a regular peer. */
5414
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5415
    /* Send notification or reset peer depending on state. */
5416
0
    if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
5417
0
      peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
5418
0
      bgp_notify_send(peer, BGP_NOTIFY_CEASE,
5419
0
          BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5420
0
    } else
5421
0
      bgp_session_reset(peer);
5422
5423
    /* Apply new source configuration to BFD session. */
5424
0
    if (peer->bfd_config)
5425
0
      bgp_peer_bfd_update_source(peer);
5426
5427
    /* Skip peer-group mechanics for regular peers. */
5428
0
    return;
5429
0
  }
5430
5431
  /*
5432
   * Set flag and configuration on all peer-group members, unless they are
5433
   * explicitly overriding peer-group configuration.
5434
   */
5435
0
  for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5436
    /* Skip peers with overridden configuration. */
5437
0
    if (CHECK_FLAG(member->flags_override, PEER_FLAG_UPDATE_SOURCE))
5438
0
      continue;
5439
5440
    /* Skip peers with the same configuration. */
5441
0
    if (!CHECK_FLAG(member->flags, PEER_FLAG_UPDATE_SOURCE)
5442
0
        && !member->update_source && !member->update_if)
5443
0
      continue;
5444
5445
    /* Remove flag and configuration on peer-group member. */
5446
0
    UNSET_FLAG(member->flags, PEER_FLAG_UPDATE_SOURCE);
5447
0
    sockunion_free(member->update_source);
5448
0
    member->update_source = NULL;
5449
0
    XFREE(MTYPE_PEER_UPDATE_SOURCE, member->update_if);
5450
5451
    /* Send notification or reset peer depending on state. */
5452
0
    if (BGP_IS_VALID_STATE_FOR_NOTIF(member->status)) {
5453
0
      member->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
5454
0
      bgp_notify_send(member, BGP_NOTIFY_CEASE,
5455
0
          BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5456
0
    } else
5457
0
      bgp_session_reset(member);
5458
5459
    /* Apply new source configuration to BFD session. */
5460
0
    if (member->bfd_config)
5461
0
      bgp_peer_bfd_update_source(member);
5462
0
  }
5463
0
}
5464
5465
int peer_default_originate_set(struct peer *peer, afi_t afi, safi_t safi,
5466
             const char *rmap, struct route_map *route_map)
5467
0
{
5468
0
  struct peer *member;
5469
0
  struct listnode *node, *nnode;
5470
0
  struct update_subgroup *subgrp;
5471
5472
  /* Set flag and configuration on peer. */
5473
0
  peer_af_flag_set(peer, afi, safi, PEER_FLAG_DEFAULT_ORIGINATE);
5474
5475
0
  subgrp = peer_subgroup(peer, afi, safi);
5476
5477
0
  if (rmap) {
5478
0
    if (!peer->default_rmap[afi][safi].name
5479
0
        || strcmp(rmap, peer->default_rmap[afi][safi].name) != 0) {
5480
0
      struct route_map *map = NULL;
5481
5482
0
      if (peer->default_rmap[afi][safi].name) {
5483
0
        map = route_map_lookup_by_name(
5484
0
          peer->default_rmap[afi][safi].name);
5485
0
        XFREE(MTYPE_ROUTE_MAP_NAME,
5486
0
              peer->default_rmap[afi][safi].name);
5487
0
      }
5488
5489
      /*
5490
       * When there is a change in route-map policy,
5491
       * this flow gets triggered. Since, the default
5492
       * route is already originated, the flag is set.
5493
       * The flag should be unset here,
5494
       * to trigger the flow of sending update message.
5495
       */
5496
0
      if (subgrp)
5497
0
        UNSET_FLAG(subgrp->sflags,
5498
0
             SUBGRP_STATUS_DEFAULT_ORIGINATE);
5499
5500
0
      route_map_counter_decrement(map);
5501
0
      peer->default_rmap[afi][safi].name =
5502
0
        XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
5503
0
      peer->default_rmap[afi][safi].map = route_map;
5504
0
      route_map_counter_increment(route_map);
5505
0
    }
5506
0
  } else if (!rmap) {
5507
0
    struct route_map *map = NULL;
5508
5509
0
    if (peer->default_rmap[afi][safi].name) {
5510
0
      map = route_map_lookup_by_name(
5511
0
        peer->default_rmap[afi][safi].name);
5512
0
      XFREE(MTYPE_ROUTE_MAP_NAME,
5513
0
            peer->default_rmap[afi][safi].name);
5514
0
    }
5515
5516
    /*
5517
     * This is triggered in case of route-map deletion.
5518
     * The flag needs to be unset, to trigger the flow
5519
     * of sending an update message.
5520
     */
5521
0
    if (subgrp)
5522
0
      UNSET_FLAG(subgrp->sflags,
5523
0
           SUBGRP_STATUS_DEFAULT_ORIGINATE);
5524
5525
0
    route_map_counter_decrement(map);
5526
0
    peer->default_rmap[afi][safi].name = NULL;
5527
0
    peer->default_rmap[afi][safi].map = NULL;
5528
0
  }
5529
5530
  /* Check if handling a regular peer. */
5531
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5532
    /* Update peer route announcements. */
5533
0
    if (peer_established(peer) && peer->afc_nego[afi][safi]) {
5534
0
      update_group_adjust_peer(peer_af_find(peer, afi, safi));
5535
0
      bgp_default_originate(peer, afi, safi, 0);
5536
0
      bgp_announce_route(peer, afi, safi, false);
5537
0
    }
5538
5539
    /* Skip peer-group mechanics for regular peers. */
5540
0
    return 0;
5541
0
  }
5542
5543
  /*
5544
   * Set flag and configuration on all peer-group members, unless they are
5545
   * explicitly overriding peer-group configuration.
5546
   */
5547
0
  for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5548
    /* Skip peers with overridden configuration. */
5549
0
    if (CHECK_FLAG(member->af_flags_override[afi][safi],
5550
0
             PEER_FLAG_DEFAULT_ORIGINATE))
5551
0
      continue;
5552
5553
    /* Set flag and configuration on peer-group member. */
5554
0
    SET_FLAG(member->af_flags[afi][safi],
5555
0
       PEER_FLAG_DEFAULT_ORIGINATE);
5556
0
    if (rmap) {
5557
0
      struct route_map *map = NULL;
5558
5559
0
      if (member->default_rmap[afi][safi].name) {
5560
0
        map = route_map_lookup_by_name(
5561
0
          member->default_rmap[afi][safi].name);
5562
0
        XFREE(MTYPE_ROUTE_MAP_NAME,
5563
0
              member->default_rmap[afi][safi].name);
5564
0
      }
5565
5566
0
      route_map_counter_decrement(map);
5567
0
      member->default_rmap[afi][safi].name =
5568
0
        XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
5569
0
      member->default_rmap[afi][safi].map = route_map;
5570
0
      route_map_counter_increment(route_map);
5571
0
    }
5572
5573
    /* Update peer route announcements. */
5574
0
    if (peer_established(member) && member->afc_nego[afi][safi]) {
5575
0
      update_group_adjust_peer(
5576
0
        peer_af_find(member, afi, safi));
5577
0
      bgp_default_originate(member, afi, safi, 0);
5578
0
      bgp_announce_route(member, afi, safi, false);
5579
0
    }
5580
0
  }
5581
5582
0
  return 0;
5583
0
}
5584
5585
int peer_default_originate_unset(struct peer *peer, afi_t afi, safi_t safi)
5586
0
{
5587
0
  struct peer *member;
5588
0
  struct listnode *node, *nnode;
5589
5590
  /* Inherit configuration from peer-group if peer is member. */
5591
0
  if (peer_group_active(peer)) {
5592
0
    peer_af_flag_inherit(peer, afi, safi,
5593
0
             PEER_FLAG_DEFAULT_ORIGINATE);
5594
0
    PEER_STR_ATTR_INHERIT(peer, peer->group,
5595
0
              default_rmap[afi][safi].name,
5596
0
              MTYPE_ROUTE_MAP_NAME);
5597
0
    PEER_ATTR_INHERIT(peer, peer->group,
5598
0
          default_rmap[afi][safi].map);
5599
0
  } else {
5600
0
    struct route_map *map = NULL;
5601
5602
    /* Otherwise remove flag and configuration from peer. */
5603
0
    peer_af_flag_unset(peer, afi, safi,
5604
0
           PEER_FLAG_DEFAULT_ORIGINATE);
5605
0
    if (peer->default_rmap[afi][safi].name) {
5606
0
      map = route_map_lookup_by_name(
5607
0
        peer->default_rmap[afi][safi].name);
5608
0
      XFREE(MTYPE_ROUTE_MAP_NAME,
5609
0
            peer->default_rmap[afi][safi].name);
5610
0
    }
5611
0
    route_map_counter_decrement(map);
5612
0
    peer->default_rmap[afi][safi].name = NULL;
5613
0
    peer->default_rmap[afi][safi].map = NULL;
5614
0
  }
5615
5616
  /* Check if handling a regular peer. */
5617
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5618
    /* Update peer route announcements. */
5619
0
    if (peer_established(peer) && peer->afc_nego[afi][safi]) {
5620
0
      update_group_adjust_peer(peer_af_find(peer, afi, safi));
5621
0
      bgp_default_originate(peer, afi, safi, 1);
5622
0
      bgp_announce_route(peer, afi, safi, false);
5623
0
    }
5624
5625
    /* Skip peer-group mechanics for regular peers. */
5626
0
    return 0;
5627
0
  }
5628
5629
  /*
5630
   * Remove flag and configuration from all peer-group members, unless
5631
   * they are explicitly overriding peer-group configuration.
5632
   */
5633
0
  for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5634
0
    struct route_map *map;
5635
5636
0
    map = NULL;
5637
5638
    /* Skip peers with overridden configuration. */
5639
0
    if (CHECK_FLAG(member->af_flags_override[afi][safi],
5640
0
             PEER_FLAG_DEFAULT_ORIGINATE))
5641
0
      continue;
5642
5643
    /* Remove flag and configuration on peer-group member. */
5644
0
    UNSET_FLAG(member->af_flags[afi][safi],
5645
0
         PEER_FLAG_DEFAULT_ORIGINATE);
5646
0
    if (member->default_rmap[afi][safi].name) {
5647
0
      map = route_map_lookup_by_name(
5648
0
        member->default_rmap[afi][safi].name);
5649
0
      XFREE(MTYPE_ROUTE_MAP_NAME,
5650
0
            member->default_rmap[afi][safi].name);
5651
0
    }
5652
0
    route_map_counter_decrement(map);
5653
0
    member->default_rmap[afi][safi].name = NULL;
5654
0
    member->default_rmap[afi][safi].map = NULL;
5655
5656
    /* Update peer route announcements. */
5657
0
    if (peer_established(member) && member->afc_nego[afi][safi]) {
5658
0
      update_group_adjust_peer(peer_af_find(member, afi, safi));
5659
0
      bgp_default_originate(member, afi, safi, 1);
5660
0
      bgp_announce_route(member, afi, safi, false);
5661
0
    }
5662
0
  }
5663
5664
0
  return 0;
5665
0
}
5666
5667
void peer_port_set(struct peer *peer, uint16_t port)
5668
0
{
5669
0
  peer->port = port;
5670
0
  peer_flag_set(peer, PEER_FLAG_PORT);
5671
0
}
5672
5673
void peer_port_unset(struct peer *peer)
5674
0
{
5675
0
  peer->port = BGP_PORT_DEFAULT;
5676
0
  peer_flag_unset(peer, PEER_FLAG_PORT);
5677
0
}
5678
5679
/* Set the TCP-MSS value in the peer structure,
5680
 * This gets applied only after connection reset
5681
 * So this value will be used in bgp_connect.
5682
 */
5683
void peer_tcp_mss_set(struct peer *peer, uint32_t tcp_mss)
5684
0
{
5685
0
  peer->tcp_mss = tcp_mss;
5686
0
  SET_FLAG(peer->flags, PEER_FLAG_TCP_MSS);
5687
0
}
5688
5689
/* Reset the TCP-MSS value in the peer structure,
5690
 * This gets applied only after connection reset
5691
 * So this value will be used in bgp_connect.
5692
 */
5693
void peer_tcp_mss_unset(struct peer *peer)
5694
0
{
5695
0
  UNSET_FLAG(peer->flags, PEER_FLAG_TCP_MSS);
5696
0
  peer->tcp_mss = 0;
5697
0
}
5698
5699
/*
5700
 * Helper function that is called after the name of the policy
5701
 * being used by a peer has changed (AF specific). Automatically
5702
 * initiates inbound or outbound processing as needed.
5703
 */
5704
void peer_on_policy_change(struct peer *peer, afi_t afi, safi_t safi,
5705
         int outbound)
5706
0
{
5707
0
  if (outbound) {
5708
0
    update_group_adjust_peer(peer_af_find(peer, afi, safi));
5709
0
    if (peer_established(peer))
5710
0
      bgp_announce_route(peer, afi, safi, false);
5711
0
  } else {
5712
0
    if (!peer_established(peer))
5713
0
      return;
5714
5715
0
    if (bgp_soft_reconfig_in(peer, afi, safi))
5716
0
      return;
5717
5718
0
    if (CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_OLD_RCV) ||
5719
0
        CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_NEW_RCV))
5720
0
      bgp_route_refresh_send(peer, afi, safi, 0, 0, 0,
5721
0
                 BGP_ROUTE_REFRESH_NORMAL);
5722
0
  }
5723
0
}
5724
5725
5726
/* neighbor weight. */
5727
int peer_weight_set(struct peer *peer, afi_t afi, safi_t safi, uint16_t weight)
5728
0
{
5729
0
  struct peer *member;
5730
0
  struct listnode *node, *nnode;
5731
5732
  /* Set flag and configuration on peer. */
5733
0
  peer_af_flag_set(peer, afi, safi, PEER_FLAG_WEIGHT);
5734
0
  if (peer->weight[afi][safi] != weight) {
5735
0
    peer->weight[afi][safi] = weight;
5736
0
    peer_on_policy_change(peer, afi, safi, 0);
5737
0
  }
5738
5739
  /* Skip peer-group mechanics for regular peers. */
5740
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
5741
0
    return 0;
5742
5743
  /*
5744
   * Set flag and configuration on all peer-group members, unless they are
5745
   * explicitly overriding peer-group configuration.
5746
   */
5747
0
  for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5748
    /* Skip peers with overridden configuration. */
5749
0
    if (CHECK_FLAG(member->af_flags_override[afi][safi],
5750
0
             PEER_FLAG_WEIGHT))
5751
0
      continue;
5752
5753
    /* Set flag and configuration on peer-group member. */
5754
0
    SET_FLAG(member->af_flags[afi][safi], PEER_FLAG_WEIGHT);
5755
0
    if (member->weight[afi][safi] != weight) {
5756
0
      member->weight[afi][safi] = weight;
5757
0
      peer_on_policy_change(member, afi, safi, 0);
5758
0
    }
5759
0
  }
5760
5761
0
  return 0;
5762
0
}
5763
5764
int peer_weight_unset(struct peer *peer, afi_t afi, safi_t safi)
5765
0
{
5766
0
  struct peer *member;
5767
0
  struct listnode *node, *nnode;
5768
5769
0
  if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_WEIGHT))
5770
0
    return 0;
5771
5772
  /* Inherit configuration from peer-group if peer is member. */
5773
0
  if (peer_group_active(peer)) {
5774
0
    peer_af_flag_inherit(peer, afi, safi, PEER_FLAG_WEIGHT);
5775
0
    PEER_ATTR_INHERIT(peer, peer->group, weight[afi][safi]);
5776
5777
0
    peer_on_policy_change(peer, afi, safi, 0);
5778
0
    return 0;
5779
0
  }
5780
5781
  /* Remove flag and configuration from peer. */
5782
0
  peer_af_flag_unset(peer, afi, safi, PEER_FLAG_WEIGHT);
5783
0
  peer->weight[afi][safi] = 0;
5784
0
  peer_on_policy_change(peer, afi, safi, 0);
5785
5786
  /* Skip peer-group mechanics for regular peers. */
5787
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
5788
0
    return 0;
5789
5790
  /*
5791
   * Remove flag and configuration from all peer-group members, unless
5792
   * they are explicitly overriding peer-group configuration.
5793
   */
5794
0
  for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5795
    /* Skip peers with overridden configuration. */
5796
0
    if (CHECK_FLAG(member->af_flags_override[afi][safi],
5797
0
             PEER_FLAG_WEIGHT))
5798
0
      continue;
5799
5800
    /* Skip peers where flag is already disabled. */
5801
0
    if (!CHECK_FLAG(member->af_flags[afi][safi], PEER_FLAG_WEIGHT))
5802
0
      continue;
5803
5804
    /* Remove flag and configuration on peer-group member. */
5805
0
    UNSET_FLAG(member->af_flags[afi][safi], PEER_FLAG_WEIGHT);
5806
0
    member->weight[afi][safi] = 0;
5807
0
    peer_on_policy_change(member, afi, safi, 0);
5808
0
  }
5809
5810
0
  return 0;
5811
0
}
5812
5813
int peer_timers_set(struct peer *peer, uint32_t keepalive, uint32_t holdtime)
5814
0
{
5815
0
  struct peer *member;
5816
0
  struct listnode *node, *nnode;
5817
5818
0
  if (keepalive > UINT16_MAX)
5819
0
    return BGP_ERR_INVALID_VALUE;
5820
5821
0
  if (holdtime > UINT16_MAX)
5822
0
    return BGP_ERR_INVALID_VALUE;
5823
5824
0
  if (holdtime < 3 && holdtime != 0)
5825
0
    return BGP_ERR_INVALID_VALUE;
5826
5827
  /* Set flag and configuration on peer. */
5828
0
  peer_flag_set(peer, PEER_FLAG_TIMER);
5829
0
  peer->holdtime = holdtime;
5830
0
  peer->keepalive = (keepalive < holdtime / 3 ? keepalive : holdtime / 3);
5831
5832
  /* Skip peer-group mechanics for regular peers. */
5833
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
5834
0
    return 0;
5835
5836
  /*
5837
   * Set flag and configuration on all peer-group members, unless they are
5838
   * explicitly overriding peer-group configuration.
5839
   */
5840
0
  for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5841
    /* Skip peers with overridden configuration. */
5842
0
    if (CHECK_FLAG(member->flags_override, PEER_FLAG_TIMER))
5843
0
      continue;
5844
5845
    /* Set flag and configuration on peer-group member. */
5846
0
    SET_FLAG(member->flags, PEER_FLAG_TIMER);
5847
0
    PEER_ATTR_INHERIT(member, peer->group, holdtime);
5848
0
    PEER_ATTR_INHERIT(member, peer->group, keepalive);
5849
0
  }
5850
5851
0
  return 0;
5852
0
}
5853
5854
int peer_timers_unset(struct peer *peer)
5855
0
{
5856
0
  struct peer *member;
5857
0
  struct listnode *node, *nnode;
5858
5859
  /* Inherit configuration from peer-group if peer is member. */
5860
0
  if (peer_group_active(peer)) {
5861
0
    peer_flag_inherit(peer, PEER_FLAG_TIMER);
5862
0
    PEER_ATTR_INHERIT(peer, peer->group, holdtime);
5863
0
    PEER_ATTR_INHERIT(peer, peer->group, keepalive);
5864
0
  } else {
5865
    /* Otherwise remove flag and configuration from peer. */
5866
0
    peer_flag_unset(peer, PEER_FLAG_TIMER);
5867
0
    peer->holdtime = 0;
5868
0
    peer->keepalive = 0;
5869
0
  }
5870
5871
  /* Skip peer-group mechanics for regular peers. */
5872
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
5873
0
    return 0;
5874
5875
  /*
5876
   * Remove flag and configuration from all peer-group members, unless
5877
   * they are explicitly overriding peer-group configuration.
5878
   */
5879
0
  for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5880
    /* Skip peers with overridden configuration. */
5881
0
    if (CHECK_FLAG(member->flags_override, PEER_FLAG_TIMER))
5882
0
      continue;
5883
5884
    /* Remove flag and configuration on peer-group member. */
5885
0
    UNSET_FLAG(member->flags, PEER_FLAG_TIMER);
5886
0
    member->holdtime = 0;
5887
0
    member->keepalive = 0;
5888
0
  }
5889
5890
0
  return 0;
5891
0
}
5892
5893
int peer_timers_connect_set(struct peer *peer, uint32_t connect)
5894
0
{
5895
0
  struct peer *member;
5896
0
  struct listnode *node, *nnode;
5897
5898
0
  if (connect > UINT16_MAX)
5899
0
    return BGP_ERR_INVALID_VALUE;
5900
5901
  /* Set flag and configuration on peer. */
5902
0
  peer_flag_set(peer, PEER_FLAG_TIMER_CONNECT);
5903
0
  peer->connect = connect;
5904
0
  peer->v_connect = connect;
5905
5906
  /* Skip peer-group mechanics for regular peers. */
5907
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5908
0
    if (!peer_established(peer)) {
5909
0
      if (peer_active(peer))
5910
0
        BGP_EVENT_ADD(peer, BGP_Stop);
5911
0
      BGP_EVENT_ADD(peer, BGP_Start);
5912
0
    }
5913
0
    return 0;
5914
0
  }
5915
  /*
5916
   * Set flag and configuration on all peer-group members, unless they are
5917
   * explicitly overriding peer-group configuration.
5918
   */
5919
0
  for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5920
    /* Skip peers with overridden configuration. */
5921
0
    if (CHECK_FLAG(member->flags_override, PEER_FLAG_TIMER_CONNECT))
5922
0
      continue;
5923
5924
    /* Set flag and configuration on peer-group member. */
5925
0
    SET_FLAG(member->flags, PEER_FLAG_TIMER_CONNECT);
5926
0
    member->connect = connect;
5927
0
    member->v_connect = connect;
5928
5929
0
    if (!peer_established(member)) {
5930
0
      if (peer_active(member))
5931
0
        BGP_EVENT_ADD(member, BGP_Stop);
5932
0
      BGP_EVENT_ADD(member, BGP_Start);
5933
0
    }
5934
0
  }
5935
5936
0
  return 0;
5937
0
}
5938
5939
int peer_timers_connect_unset(struct peer *peer)
5940
0
{
5941
0
  struct peer *member;
5942
0
  struct listnode *node, *nnode;
5943
5944
  /* Inherit configuration from peer-group if peer is member. */
5945
0
  if (peer_group_active(peer)) {
5946
0
    peer_flag_inherit(peer, PEER_FLAG_TIMER_CONNECT);
5947
0
    PEER_ATTR_INHERIT(peer, peer->group, connect);
5948
0
  } else {
5949
    /* Otherwise remove flag and configuration from peer. */
5950
0
    peer_flag_unset(peer, PEER_FLAG_TIMER_CONNECT);
5951
0
    peer->connect = 0;
5952
0
  }
5953
5954
  /* Set timer with fallback to default value. */
5955
0
  if (peer->connect)
5956
0
    peer->v_connect = peer->connect;
5957
0
  else
5958
0
    peer->v_connect = peer->bgp->default_connect_retry;
5959
5960
  /* Skip peer-group mechanics for regular peers. */
5961
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5962
0
    if (!peer_established(peer)) {
5963
0
      if (peer_active(peer))
5964
0
        BGP_EVENT_ADD(peer, BGP_Stop);
5965
0
      BGP_EVENT_ADD(peer, BGP_Start);
5966
0
    }
5967
0
    return 0;
5968
0
  }
5969
  /*
5970
   * Remove flag and configuration from all peer-group members, unless
5971
   * they are explicitly overriding peer-group configuration.
5972
   */
5973
0
  for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5974
    /* Skip peers with overridden configuration. */
5975
0
    if (CHECK_FLAG(member->flags_override, PEER_FLAG_TIMER_CONNECT))
5976
0
      continue;
5977
5978
    /* Remove flag and configuration on peer-group member. */
5979
0
    UNSET_FLAG(member->flags, PEER_FLAG_TIMER_CONNECT);
5980
0
    member->connect = 0;
5981
0
    member->v_connect = peer->bgp->default_connect_retry;
5982
5983
0
    if (!peer_established(member)) {
5984
0
      if (peer_active(member))
5985
0
        BGP_EVENT_ADD(member, BGP_Stop);
5986
0
      BGP_EVENT_ADD(member, BGP_Start);
5987
0
    }
5988
0
  }
5989
5990
0
  return 0;
5991
0
}
5992
5993
int peer_advertise_interval_set(struct peer *peer, uint32_t routeadv)
5994
0
{
5995
0
  struct peer *member;
5996
0
  struct listnode *node, *nnode;
5997
5998
0
  if (routeadv > 600)
5999
0
    return BGP_ERR_INVALID_VALUE;
6000
6001
  /* Set flag and configuration on peer. */
6002
0
  peer_flag_set(peer, PEER_FLAG_ROUTEADV);
6003
0
  peer->routeadv = routeadv;
6004
0
  peer->v_routeadv = routeadv;
6005
6006
  /* Check if handling a regular peer. */
6007
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6008
    /* Update peer route announcements. */
6009
0
    update_group_adjust_peer_afs(peer);
6010
0
    if (peer_established(peer))
6011
0
      bgp_announce_route_all(peer);
6012
6013
    /* Skip peer-group mechanics for regular peers. */
6014
0
    return 0;
6015
0
  }
6016
6017
  /*
6018
   * Set flag and configuration on all peer-group members, unless they are
6019
   * explicitly overriding peer-group configuration.
6020
   */
6021
0
  for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
6022
    /* Skip peers with overridden configuration. */
6023
0
    if (CHECK_FLAG(member->flags_override, PEER_FLAG_ROUTEADV))
6024
0
      continue;
6025
6026
    /* Set flag and configuration on peer-group member. */
6027
0
    SET_FLAG(member->flags, PEER_FLAG_ROUTEADV);
6028
0
    member->routeadv = routeadv;
6029
0
    member->v_routeadv = routeadv;
6030
6031
    /* Update peer route announcements. */
6032
0
    update_group_adjust_peer_afs(member);
6033
0
    if (peer_established(member))
6034
0
      bgp_announce_route_all(member);
6035
0
  }
6036
6037
0
  return 0;
6038
0
}
6039
6040
int peer_advertise_interval_unset(struct peer *peer)
6041
0
{
6042
0
  struct peer *member;
6043
0
  struct listnode *node, *nnode;
6044
6045
  /* Inherit configuration from peer-group if peer is member. */
6046
0
  if (peer_group_active(peer)) {
6047
0
    peer_flag_inherit(peer, PEER_FLAG_ROUTEADV);
6048
0
    PEER_ATTR_INHERIT(peer, peer->group, routeadv);
6049
0
  } else {
6050
    /* Otherwise remove flag and configuration from peer. */
6051
0
    peer_flag_unset(peer, PEER_FLAG_ROUTEADV);
6052
0
    peer->routeadv = 0;
6053
0
  }
6054
6055
  /* Set timer with fallback to default value. */
6056
0
  if (peer->routeadv)
6057
0
    peer->v_routeadv = peer->routeadv;
6058
0
  else
6059
0
    peer->v_routeadv = (peer->sort == BGP_PEER_IBGP)
6060
0
             ? BGP_DEFAULT_IBGP_ROUTEADV
6061
0
             : BGP_DEFAULT_EBGP_ROUTEADV;
6062
6063
  /* Check if handling a regular peer. */
6064
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6065
    /* Update peer route announcements. */
6066
0
    update_group_adjust_peer_afs(peer);
6067
0
    if (peer_established(peer))
6068
0
      bgp_announce_route_all(peer);
6069
6070
    /* Skip peer-group mechanics for regular peers. */
6071
0
    return 0;
6072
0
  }
6073
6074
  /*
6075
   * Remove flag and configuration from all peer-group members, unless
6076
   * they are explicitly overriding peer-group configuration.
6077
   */
6078
0
  for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
6079
    /* Skip peers with overridden configuration. */
6080
0
    if (CHECK_FLAG(member->flags_override, PEER_FLAG_ROUTEADV))
6081
0
      continue;
6082
6083
    /* Remove flag and configuration on peer-group member. */
6084
0
    UNSET_FLAG(member->flags, PEER_FLAG_ROUTEADV);
6085
0
    member->routeadv = 0;
6086
0
    member->v_routeadv = (member->sort == BGP_PEER_IBGP)
6087
0
               ? BGP_DEFAULT_IBGP_ROUTEADV
6088
0
               : BGP_DEFAULT_EBGP_ROUTEADV;
6089
6090
    /* Update peer route announcements. */
6091
0
    update_group_adjust_peer_afs(member);
6092
0
    if (peer_established(member))
6093
0
      bgp_announce_route_all(member);
6094
0
  }
6095
6096
0
  return 0;
6097
0
}
6098
6099
/* set the peers RFC 4271 DelayOpen session attribute flag and DelayOpenTimer
6100
 * interval
6101
 */
6102
int peer_timers_delayopen_set(struct peer *peer, uint32_t delayopen)
6103
0
{
6104
0
  struct peer *member;
6105
0
  struct listnode *node;
6106
6107
  /* Set peers session attribute flag and timer interval. */
6108
0
  peer_flag_set(peer, PEER_FLAG_TIMER_DELAYOPEN);
6109
0
  peer->delayopen = delayopen;
6110
0
  peer->v_delayopen = delayopen;
6111
6112
  /* Skip group mechanics for regular peers. */
6113
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
6114
0
    return 0;
6115
6116
  /* Set flag and configuration on all peer-group members, unless they are
6117
   * explicitly overriding peer-group configuration.
6118
   */
6119
0
  for (ALL_LIST_ELEMENTS_RO(peer->group->peer, node, member)) {
6120
    /* Skip peers with overridden configuration. */
6121
0
    if (CHECK_FLAG(member->flags_override,
6122
0
             PEER_FLAG_TIMER_DELAYOPEN))
6123
0
      continue;
6124
6125
    /* Set session attribute flag and timer intervals on peer-group
6126
     * member.
6127
     */
6128
0
    SET_FLAG(member->flags, PEER_FLAG_TIMER_DELAYOPEN);
6129
0
    member->delayopen = delayopen;
6130
0
    member->v_delayopen = delayopen;
6131
0
  }
6132
6133
0
  return 0;
6134
0
}
6135
6136
/* unset the peers RFC 4271 DelayOpen session attribute flag and reset the
6137
 * DelayOpenTimer interval to the default value.
6138
 */
6139
int peer_timers_delayopen_unset(struct peer *peer)
6140
0
{
6141
0
  struct peer *member;
6142
0
  struct listnode *node;
6143
6144
  /* Inherit configuration from peer-group if peer is member. */
6145
0
  if (peer_group_active(peer)) {
6146
0
    peer_flag_inherit(peer, PEER_FLAG_TIMER_DELAYOPEN);
6147
0
    PEER_ATTR_INHERIT(peer, peer->group, delayopen);
6148
0
  } else {
6149
    /* Otherwise remove session attribute flag and set timer
6150
     * interval to default value.
6151
     */
6152
0
    peer_flag_unset(peer, PEER_FLAG_TIMER_DELAYOPEN);
6153
0
    peer->delayopen = peer->bgp->default_delayopen;
6154
0
  }
6155
6156
  /* Set timer value to zero */
6157
0
  peer->v_delayopen = 0;
6158
6159
  /* Skip peer-group mechanics for regular peers. */
6160
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
6161
0
    return 0;
6162
6163
  /* Remove flag and configuration from all peer-group members, unless
6164
   * they are explicitly overriding peer-group configuration.
6165
   */
6166
0
  for (ALL_LIST_ELEMENTS_RO(peer->group->peer, node, member)) {
6167
    /* Skip peers with overridden configuration. */
6168
0
    if (CHECK_FLAG(member->flags_override,
6169
0
             PEER_FLAG_TIMER_DELAYOPEN))
6170
0
      continue;
6171
6172
    /* Remove session attribute flag, reset the timer interval to
6173
     * the default value and set the timer value to zero.
6174
     */
6175
0
    UNSET_FLAG(member->flags, PEER_FLAG_TIMER_DELAYOPEN);
6176
0
    member->delayopen = peer->bgp->default_delayopen;
6177
0
    member->v_delayopen = 0;
6178
0
  }
6179
6180
0
  return 0;
6181
0
}
6182
6183
/* neighbor interface */
6184
void peer_interface_set(struct peer *peer, const char *str)
6185
0
{
6186
0
  XFREE(MTYPE_BGP_PEER_IFNAME, peer->ifname);
6187
0
  peer->ifname = XSTRDUP(MTYPE_BGP_PEER_IFNAME, str);
6188
0
}
6189
6190
void peer_interface_unset(struct peer *peer)
6191
0
{
6192
0
  XFREE(MTYPE_BGP_PEER_IFNAME, peer->ifname);
6193
0
}
6194
6195
/* Allow-as in.  */
6196
int peer_allowas_in_set(struct peer *peer, afi_t afi, safi_t safi,
6197
      int allow_num, int origin)
6198
0
{
6199
0
  struct peer *member;
6200
0
  struct listnode *node, *nnode;
6201
6202
0
  if (!origin && (allow_num < 1 || allow_num > 10))
6203
0
    return BGP_ERR_INVALID_VALUE;
6204
6205
  /* Set flag and configuration on peer. */
6206
0
  peer_af_flag_set(peer, afi, safi, PEER_FLAG_ALLOWAS_IN);
6207
0
  if (origin) {
6208
0
    if (peer->allowas_in[afi][safi] != 0
6209
0
        || !CHECK_FLAG(peer->af_flags[afi][safi],
6210
0
           PEER_FLAG_ALLOWAS_IN_ORIGIN)) {
6211
0
      peer_af_flag_set(peer, afi, safi,
6212
0
           PEER_FLAG_ALLOWAS_IN_ORIGIN);
6213
0
      peer->allowas_in[afi][safi] = 0;
6214
0
      peer_on_policy_change(peer, afi, safi, 0);
6215
0
    }
6216
0
  } else {
6217
0
    if (peer->allowas_in[afi][safi] != allow_num
6218
0
        || CHECK_FLAG(peer->af_flags[afi][safi],
6219
0
          PEER_FLAG_ALLOWAS_IN_ORIGIN)) {
6220
6221
0
      peer_af_flag_unset(peer, afi, safi,
6222
0
             PEER_FLAG_ALLOWAS_IN_ORIGIN);
6223
0
      peer->allowas_in[afi][safi] = allow_num;
6224
0
      peer_on_policy_change(peer, afi, safi, 0);
6225
0
    }
6226
0
  }
6227
6228
  /* Skip peer-group mechanics for regular peers. */
6229
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
6230
0
    return 0;
6231
6232
  /*
6233
   * Set flag and configuration on all peer-group members, unless
6234
   * they are explicitly overriding peer-group configuration.
6235
   */
6236
0
  for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
6237
    /* Skip peers with overridden configuration. */
6238
0
    if (CHECK_FLAG(member->af_flags_override[afi][safi],
6239
0
             PEER_FLAG_ALLOWAS_IN))
6240
0
      continue;
6241
6242
    /* Set flag and configuration on peer-group member. */
6243
0
    SET_FLAG(member->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN);
6244
0
    if (origin) {
6245
0
      if (member->allowas_in[afi][safi] != 0
6246
0
          || !CHECK_FLAG(member->af_flags[afi][safi],
6247
0
             PEER_FLAG_ALLOWAS_IN_ORIGIN)) {
6248
0
        SET_FLAG(member->af_flags[afi][safi],
6249
0
           PEER_FLAG_ALLOWAS_IN_ORIGIN);
6250
0
        member->allowas_in[afi][safi] = 0;
6251
0
        peer_on_policy_change(peer, afi, safi, 0);
6252
0
      }
6253
0
    } else {
6254
0
      if (member->allowas_in[afi][safi] != allow_num
6255
0
          || CHECK_FLAG(member->af_flags[afi][safi],
6256
0
            PEER_FLAG_ALLOWAS_IN_ORIGIN)) {
6257
0
        UNSET_FLAG(member->af_flags[afi][safi],
6258
0
             PEER_FLAG_ALLOWAS_IN_ORIGIN);
6259
0
        member->allowas_in[afi][safi] = allow_num;
6260
0
        peer_on_policy_change(peer, afi, safi, 0);
6261
0
      }
6262
0
    }
6263
0
  }
6264
6265
0
  return 0;
6266
0
}
6267
6268
int peer_allowas_in_unset(struct peer *peer, afi_t afi, safi_t safi)
6269
0
{
6270
0
  struct peer *member;
6271
0
  struct listnode *node, *nnode;
6272
6273
  /* Skip peer if flag is already disabled. */
6274
0
  if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN))
6275
0
    return 0;
6276
6277
  /* Inherit configuration from peer-group if peer is member. */
6278
0
  if (peer_group_active(peer)) {
6279
0
    peer_af_flag_inherit(peer, afi, safi, PEER_FLAG_ALLOWAS_IN);
6280
0
    peer_af_flag_inherit(peer, afi, safi,
6281
0
             PEER_FLAG_ALLOWAS_IN_ORIGIN);
6282
0
    PEER_ATTR_INHERIT(peer, peer->group, allowas_in[afi][safi]);
6283
0
    peer_on_policy_change(peer, afi, safi, 0);
6284
6285
0
    return 0;
6286
0
  }
6287
6288
  /* Remove flag and configuration from peer. */
6289
0
  peer_af_flag_unset(peer, afi, safi, PEER_FLAG_ALLOWAS_IN);
6290
0
  peer_af_flag_unset(peer, afi, safi, PEER_FLAG_ALLOWAS_IN_ORIGIN);
6291
0
  peer->allowas_in[afi][safi] = 0;
6292
0
  peer_on_policy_change(peer, afi, safi, 0);
6293
6294
  /* Skip peer-group mechanics if handling a regular peer. */
6295
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
6296
0
    return 0;
6297
6298
  /*
6299
   * Remove flags and configuration from all peer-group members, unless
6300
   * they are explicitly overriding peer-group configuration.
6301
   */
6302
0
  for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
6303
    /* Skip peers with overridden configuration. */
6304
0
    if (CHECK_FLAG(member->af_flags_override[afi][safi],
6305
0
             PEER_FLAG_ALLOWAS_IN))
6306
0
      continue;
6307
6308
    /* Remove flags and configuration on peer-group member. */
6309
0
    UNSET_FLAG(member->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN);
6310
0
    UNSET_FLAG(member->af_flags[afi][safi],
6311
0
         PEER_FLAG_ALLOWAS_IN_ORIGIN);
6312
0
    member->allowas_in[afi][safi] = 0;
6313
0
    peer_on_policy_change(member, afi, safi, 0);
6314
0
  }
6315
6316
0
  return 0;
6317
0
}
6318
6319
int peer_local_as_set(struct peer *peer, as_t as, bool no_prepend,
6320
          bool replace_as, const char *as_str)
6321
0
{
6322
0
  bool old_no_prepend, old_replace_as;
6323
0
  struct bgp *bgp = peer->bgp;
6324
0
  struct peer *member;
6325
0
  struct listnode *node, *nnode;
6326
6327
0
  if (bgp->as == as)
6328
0
    return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS;
6329
6330
  /* Save previous flag states. */
6331
0
  old_no_prepend =
6332
0
    !!CHECK_FLAG(peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
6333
0
  old_replace_as =
6334
0
    !!CHECK_FLAG(peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
6335
6336
  /* Set flag and configuration on peer. */
6337
0
  peer_flag_set(peer, PEER_FLAG_LOCAL_AS);
6338
0
  peer_flag_modify(peer, PEER_FLAG_LOCAL_AS_NO_PREPEND, no_prepend);
6339
0
  peer_flag_modify(peer, PEER_FLAG_LOCAL_AS_REPLACE_AS, replace_as);
6340
6341
0
  if (peer->change_local_as == as && old_no_prepend == no_prepend
6342
0
      && old_replace_as == replace_as)
6343
0
    return 0;
6344
0
  peer->change_local_as = as;
6345
0
  if (as_str) {
6346
0
    if (peer->change_local_as_pretty)
6347
0
      XFREE(MTYPE_BGP, peer->change_local_as_pretty);
6348
0
    peer->change_local_as_pretty = XSTRDUP(MTYPE_BGP, as_str);
6349
0
  }
6350
6351
0
  (void)peer_sort(peer);
6352
6353
  /* Check if handling a regular peer. */
6354
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
6355
0
    return 0;
6356
6357
  /*
6358
   * Set flag and configuration on all peer-group members, unless they are
6359
   * explicitly overriding peer-group configuration.
6360
   */
6361
0
  for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
6362
    /* Skip peers with overridden configuration. */
6363
0
    if (CHECK_FLAG(member->flags_override, PEER_FLAG_LOCAL_AS))
6364
0
      continue;
6365
6366
    /* Skip peers with the same configuration. */
6367
0
    old_no_prepend = CHECK_FLAG(member->flags,
6368
0
              PEER_FLAG_LOCAL_AS_NO_PREPEND);
6369
0
    old_replace_as = CHECK_FLAG(member->flags,
6370
0
              PEER_FLAG_LOCAL_AS_REPLACE_AS);
6371
0
    if (member->change_local_as == as
6372
0
        && CHECK_FLAG(member->flags, PEER_FLAG_LOCAL_AS)
6373
0
        && old_no_prepend == no_prepend
6374
0
        && old_replace_as == replace_as)
6375
0
      continue;
6376
6377
    /* Set flag and configuration on peer-group member. */
6378
0
    SET_FLAG(member->flags, PEER_FLAG_LOCAL_AS);
6379
0
    COND_FLAG(member->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND,
6380
0
        no_prepend);
6381
0
    COND_FLAG(member->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS,
6382
0
        replace_as);
6383
0
    member->change_local_as = as;
6384
0
    if (as_str)
6385
0
      member->change_local_as_pretty =
6386
0
        XSTRDUP(MTYPE_BGP, as_str);
6387
0
  }
6388
6389
0
  return 0;
6390
0
}
6391
6392
int peer_local_as_unset(struct peer *peer)
6393
0
{
6394
0
  struct peer *member;
6395
0
  struct listnode *node, *nnode;
6396
6397
0
  if (!CHECK_FLAG(peer->flags, PEER_FLAG_LOCAL_AS))
6398
0
    return 0;
6399
6400
  /* Inherit configuration from peer-group if peer is member. */
6401
0
  if (peer_group_active(peer)) {
6402
0
    peer_flag_inherit(peer, PEER_FLAG_LOCAL_AS);
6403
0
    peer_flag_inherit(peer, PEER_FLAG_LOCAL_AS_NO_PREPEND);
6404
0
    peer_flag_inherit(peer, PEER_FLAG_LOCAL_AS_REPLACE_AS);
6405
0
    PEER_ATTR_INHERIT(peer, peer->group, change_local_as);
6406
0
  } else {
6407
    /* Otherwise remove flag and configuration from peer. */
6408
0
    peer_flag_unset(peer, PEER_FLAG_LOCAL_AS);
6409
0
    peer_flag_unset(peer, PEER_FLAG_LOCAL_AS_NO_PREPEND);
6410
0
    peer_flag_unset(peer, PEER_FLAG_LOCAL_AS_REPLACE_AS);
6411
0
    peer->change_local_as = 0;
6412
0
    XFREE(MTYPE_BGP, peer->change_local_as_pretty);
6413
0
  }
6414
6415
  /* Check if handling a regular peer. */
6416
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6417
    /* Send notification or stop peer depending on state. */
6418
0
    if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
6419
0
      peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
6420
0
      bgp_notify_send(peer, BGP_NOTIFY_CEASE,
6421
0
          BGP_NOTIFY_CEASE_CONFIG_CHANGE);
6422
0
    } else
6423
0
      BGP_EVENT_ADD(peer, BGP_Stop);
6424
6425
    /* Skip peer-group mechanics for regular peers. */
6426
0
    return 0;
6427
0
  }
6428
6429
  /*
6430
   * Remove flag and configuration from all peer-group members, unless
6431
   * they are explicitly overriding peer-group configuration.
6432
   */
6433
0
  for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
6434
    /* Skip peers with overridden configuration. */
6435
0
    if (CHECK_FLAG(member->flags_override, PEER_FLAG_LOCAL_AS))
6436
0
      continue;
6437
6438
    /* Remove flag and configuration on peer-group member. */
6439
0
    UNSET_FLAG(member->flags, PEER_FLAG_LOCAL_AS);
6440
0
    UNSET_FLAG(member->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
6441
0
    UNSET_FLAG(member->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
6442
0
    member->change_local_as = 0;
6443
0
    XFREE(MTYPE_BGP, member->change_local_as_pretty);
6444
6445
    /* Send notification or stop peer depending on state. */
6446
0
    if (BGP_IS_VALID_STATE_FOR_NOTIF(member->status)) {
6447
0
      member->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
6448
0
      bgp_notify_send(member, BGP_NOTIFY_CEASE,
6449
0
          BGP_NOTIFY_CEASE_CONFIG_CHANGE);
6450
0
    } else
6451
0
      bgp_session_reset(member);
6452
0
  }
6453
6454
0
  return 0;
6455
0
}
6456
6457
/* Set password for authenticating with the peer. */
6458
int peer_password_set(struct peer *peer, const char *password)
6459
0
{
6460
0
  struct peer *member;
6461
0
  struct listnode *node, *nnode;
6462
0
  int len = password ? strlen(password) : 0;
6463
0
  int ret = BGP_SUCCESS;
6464
6465
0
  if ((len < PEER_PASSWORD_MINLEN) || (len > PEER_PASSWORD_MAXLEN))
6466
0
    return BGP_ERR_INVALID_VALUE;
6467
6468
  /* Set flag and configuration on peer. */
6469
0
  peer_flag_set(peer, PEER_FLAG_PASSWORD);
6470
0
  if (peer->password && strcmp(peer->password, password) == 0)
6471
0
    return 0;
6472
0
  XFREE(MTYPE_PEER_PASSWORD, peer->password);
6473
0
  peer->password = XSTRDUP(MTYPE_PEER_PASSWORD, password);
6474
6475
  /* Check if handling a regular peer. */
6476
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6477
    /* Send notification or reset peer depending on state. */
6478
0
    if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
6479
0
      bgp_notify_send(peer, BGP_NOTIFY_CEASE,
6480
0
          BGP_NOTIFY_CEASE_CONFIG_CHANGE);
6481
0
    else
6482
0
      bgp_session_reset(peer);
6483
6484
    /*
6485
     * Attempt to install password on socket and skip peer-group
6486
     * mechanics.
6487
     */
6488
0
    if (BGP_PEER_SU_UNSPEC(peer))
6489
0
      return BGP_SUCCESS;
6490
0
    return (bgp_md5_set(peer) >= 0) ? BGP_SUCCESS
6491
0
            : BGP_ERR_TCPSIG_FAILED;
6492
0
  }
6493
6494
  /*
6495
   * Set flag and configuration on all peer-group members, unless they are
6496
   * explicitly overriding peer-group configuration.
6497
   */
6498
0
  for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
6499
    /* Skip peers with overridden configuration. */
6500
0
    if (CHECK_FLAG(member->flags_override, PEER_FLAG_PASSWORD))
6501
0
      continue;
6502
6503
    /* Skip peers with the same password. */
6504
0
    if (member->password && strcmp(member->password, password) == 0)
6505
0
      continue;
6506
6507
    /* Set flag and configuration on peer-group member. */
6508
0
    SET_FLAG(member->flags, PEER_FLAG_PASSWORD);
6509
0
    if (member->password)
6510
0
      XFREE(MTYPE_PEER_PASSWORD, member->password);
6511
0
    member->password = XSTRDUP(MTYPE_PEER_PASSWORD, password);
6512
6513
    /* Send notification or reset peer depending on state. */
6514
0
    if (BGP_IS_VALID_STATE_FOR_NOTIF(member->status))
6515
0
      bgp_notify_send(member, BGP_NOTIFY_CEASE,
6516
0
          BGP_NOTIFY_CEASE_CONFIG_CHANGE);
6517
0
    else
6518
0
      bgp_session_reset(member);
6519
6520
    /* Attempt to install password on socket. */
6521
0
    if (!BGP_PEER_SU_UNSPEC(member) && bgp_md5_set(member) < 0)
6522
0
      ret = BGP_ERR_TCPSIG_FAILED;
6523
0
  }
6524
6525
  /* Set flag and configuration on all peer-group listen ranges */
6526
0
  struct listnode *ln;
6527
0
  struct prefix *lr;
6528
6529
0
  for (ALL_LIST_ELEMENTS_RO(peer->group->listen_range[AFI_IP], ln, lr))
6530
0
    bgp_md5_set_prefix(peer->bgp, lr, password);
6531
0
  for (ALL_LIST_ELEMENTS_RO(peer->group->listen_range[AFI_IP6], ln, lr))
6532
0
    bgp_md5_set_prefix(peer->bgp, lr, password);
6533
6534
0
  return ret;
6535
0
}
6536
6537
int peer_password_unset(struct peer *peer)
6538
0
{
6539
0
  struct peer *member;
6540
0
  struct listnode *node, *nnode;
6541
6542
0
  if (!CHECK_FLAG(peer->flags, PEER_FLAG_PASSWORD))
6543
0
    return 0;
6544
6545
  /* Inherit configuration from peer-group if peer is member. */
6546
0
  if (peer_group_active(peer)) {
6547
0
    peer_flag_inherit(peer, PEER_FLAG_PASSWORD);
6548
0
    PEER_STR_ATTR_INHERIT(peer, peer->group, password,
6549
0
              MTYPE_PEER_PASSWORD);
6550
0
  } else {
6551
    /* Otherwise remove flag and configuration from peer. */
6552
0
    peer_flag_unset(peer, PEER_FLAG_PASSWORD);
6553
0
    XFREE(MTYPE_PEER_PASSWORD, peer->password);
6554
0
  }
6555
6556
  /* Check if handling a regular peer. */
6557
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6558
    /* Send notification or reset peer depending on state. */
6559
0
    if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
6560
0
      bgp_notify_send(peer, BGP_NOTIFY_CEASE,
6561
0
          BGP_NOTIFY_CEASE_CONFIG_CHANGE);
6562
0
    else
6563
0
      bgp_session_reset(peer);
6564
6565
    /* Attempt to uninstall password on socket. */
6566
0
    if (!BGP_PEER_SU_UNSPEC(peer))
6567
0
      bgp_md5_unset(peer);
6568
    /* Skip peer-group mechanics for regular peers. */
6569
0
    return 0;
6570
0
  }
6571
6572
  /*
6573
   * Remove flag and configuration from all peer-group members, unless
6574
   * they are explicitly overriding peer-group configuration.
6575
   */
6576
0
  for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
6577
    /* Skip peers with overridden configuration. */
6578
0
    if (CHECK_FLAG(member->flags_override, PEER_FLAG_PASSWORD))
6579
0
      continue;
6580
6581
    /* Remove flag and configuration on peer-group member. */
6582
0
    UNSET_FLAG(member->flags, PEER_FLAG_PASSWORD);
6583
0
    XFREE(MTYPE_PEER_PASSWORD, member->password);
6584
6585
    /* Send notification or reset peer depending on state. */
6586
0
    if (BGP_IS_VALID_STATE_FOR_NOTIF(member->status))
6587
0
      bgp_notify_send(member, BGP_NOTIFY_CEASE,
6588
0
          BGP_NOTIFY_CEASE_CONFIG_CHANGE);
6589
0
    else
6590
0
      bgp_session_reset(member);
6591
6592
    /* Attempt to uninstall password on socket. */
6593
0
    if (!BGP_PEER_SU_UNSPEC(member))
6594
0
      bgp_md5_unset(member);
6595
0
  }
6596
6597
  /* Set flag and configuration on all peer-group listen ranges */
6598
0
  struct listnode *ln;
6599
0
  struct prefix *lr;
6600
6601
0
  for (ALL_LIST_ELEMENTS_RO(peer->group->listen_range[AFI_IP], ln, lr))
6602
0
    bgp_md5_unset_prefix(peer->bgp, lr);
6603
0
  for (ALL_LIST_ELEMENTS_RO(peer->group->listen_range[AFI_IP6], ln, lr))
6604
0
    bgp_md5_unset_prefix(peer->bgp, lr);
6605
6606
0
  return 0;
6607
0
}
6608
6609
6610
/* Set distribute list to the peer. */
6611
int peer_distribute_set(struct peer *peer, afi_t afi, safi_t safi, int direct,
6612
      const char *name)
6613
0
{
6614
0
  struct peer *member;
6615
0
  struct bgp_filter *filter;
6616
0
  struct listnode *node, *nnode;
6617
6618
0
  if (direct != FILTER_IN && direct != FILTER_OUT)
6619
0
    return BGP_ERR_INVALID_VALUE;
6620
6621
  /* Set configuration on peer. */
6622
0
  filter = &peer->filter[afi][safi];
6623
0
  if (filter->plist[direct].name)
6624
0
    return BGP_ERR_PEER_FILTER_CONFLICT;
6625
0
  if (filter->dlist[direct].name)
6626
0
    XFREE(MTYPE_BGP_FILTER_NAME, filter->dlist[direct].name);
6627
0
  filter->dlist[direct].name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
6628
0
  filter->dlist[direct].alist = access_list_lookup(afi, name);
6629
6630
  /* Check if handling a regular peer. */
6631
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6632
    /* Set override-flag and process peer route updates. */
6633
0
    SET_FLAG(peer->filter_override[afi][safi][direct],
6634
0
       PEER_FT_DISTRIBUTE_LIST);
6635
0
    peer_on_policy_change(peer, afi, safi,
6636
0
              (direct == FILTER_OUT) ? 1 : 0);
6637
6638
    /* Skip peer-group mechanics for regular peers. */
6639
0
    return 0;
6640
0
  }
6641
6642
  /*
6643
   * Set configuration on all peer-group members, un less they are
6644
   * explicitly overriding peer-group configuration.
6645
   */
6646
0
  for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
6647
    /* Skip peers with overridden configuration. */
6648
0
    if (CHECK_FLAG(member->filter_override[afi][safi][direct],
6649
0
             PEER_FT_DISTRIBUTE_LIST))
6650
0
      continue;
6651
6652
    /* Set configuration on peer-group member. */
6653
0
    filter = &member->filter[afi][safi];
6654
0
    if (filter->dlist[direct].name)
6655
0
      XFREE(MTYPE_BGP_FILTER_NAME,
6656
0
            filter->dlist[direct].name);
6657
0
    filter->dlist[direct].name =
6658
0
      XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
6659
0
    filter->dlist[direct].alist = access_list_lookup(afi, name);
6660
6661
    /* Process peer route updates. */
6662
0
    peer_on_policy_change(member, afi, safi,
6663
0
              (direct == FILTER_OUT) ? 1 : 0);
6664
0
  }
6665
6666
0
  return 0;
6667
0
}
6668
6669
int peer_distribute_unset(struct peer *peer, afi_t afi, safi_t safi, int direct)
6670
0
{
6671
0
  struct peer *member;
6672
0
  struct bgp_filter *filter;
6673
0
  struct listnode *node, *nnode;
6674
6675
0
  if (direct != FILTER_IN && direct != FILTER_OUT)
6676
0
    return BGP_ERR_INVALID_VALUE;
6677
6678
  /* Unset override-flag unconditionally. */
6679
0
  UNSET_FLAG(peer->filter_override[afi][safi][direct],
6680
0
       PEER_FT_DISTRIBUTE_LIST);
6681
6682
  /* Inherit configuration from peer-group if peer is member. */
6683
0
  if (peer_group_active(peer)) {
6684
0
    PEER_STR_ATTR_INHERIT(peer, peer->group,
6685
0
              filter[afi][safi].dlist[direct].name,
6686
0
              MTYPE_BGP_FILTER_NAME);
6687
0
    PEER_ATTR_INHERIT(peer, peer->group,
6688
0
          filter[afi][safi].dlist[direct].alist);
6689
0
  } else {
6690
    /* Otherwise remove configuration from peer. */
6691
0
    filter = &peer->filter[afi][safi];
6692
0
    if (filter->dlist[direct].name)
6693
0
      XFREE(MTYPE_BGP_FILTER_NAME,
6694
0
            filter->dlist[direct].name);
6695
0
    filter->dlist[direct].name = NULL;
6696
0
    filter->dlist[direct].alist = NULL;
6697
0
  }
6698
6699
  /* Check if handling a regular peer. */
6700
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6701
    /* Process peer route updates. */
6702
0
    peer_on_policy_change(peer, afi, safi,
6703
0
              (direct == FILTER_OUT) ? 1 : 0);
6704
6705
    /* Skip peer-group mechanics for regular peers. */
6706
0
    return 0;
6707
0
  }
6708
6709
  /*
6710
   * Remove configuration on all peer-group members, unless they are
6711
   * explicitly overriding peer-group configuration.
6712
   */
6713
0
  for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
6714
    /* Skip peers with overridden configuration. */
6715
0
    if (CHECK_FLAG(member->filter_override[afi][safi][direct],
6716
0
             PEER_FT_DISTRIBUTE_LIST))
6717
0
      continue;
6718
6719
    /* Remove configuration on peer-group member. */
6720
0
    filter = &member->filter[afi][safi];
6721
0
    if (filter->dlist[direct].name)
6722
0
      XFREE(MTYPE_BGP_FILTER_NAME,
6723
0
            filter->dlist[direct].name);
6724
0
    filter->dlist[direct].name = NULL;
6725
0
    filter->dlist[direct].alist = NULL;
6726
6727
    /* Process peer route updates. */
6728
0
    peer_on_policy_change(member, afi, safi,
6729
0
              (direct == FILTER_OUT) ? 1 : 0);
6730
0
  }
6731
6732
0
  return 0;
6733
0
}
6734
6735
/* Update distribute list. */
6736
static void peer_distribute_update(struct access_list *access)
6737
0
{
6738
0
  afi_t afi;
6739
0
  safi_t safi;
6740
0
  int direct;
6741
0
  struct listnode *mnode, *mnnode;
6742
0
  struct listnode *node, *nnode;
6743
0
  struct bgp *bgp;
6744
0
  struct peer *peer;
6745
0
  struct peer_group *group;
6746
0
  struct bgp_filter *filter;
6747
6748
0
  for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
6749
0
    if (access->name)
6750
0
      update_group_policy_update(bgp,
6751
0
               BGP_POLICY_DISTRIBUTE_LIST,
6752
0
               access->name, true, 0);
6753
0
    for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
6754
0
      FOREACH_AFI_SAFI (afi, safi) {
6755
0
        filter = &peer->filter[afi][safi];
6756
6757
0
        for (direct = FILTER_IN; direct < FILTER_MAX;
6758
0
             direct++) {
6759
0
          if (filter->dlist[direct].name)
6760
0
            filter->dlist[direct]
6761
0
              .alist = access_list_lookup(
6762
0
              afi,
6763
0
              filter->dlist[direct]
6764
0
                .name);
6765
0
          else
6766
0
            filter->dlist[direct].alist =
6767
0
              NULL;
6768
0
        }
6769
0
      }
6770
0
    }
6771
0
    for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) {
6772
0
      FOREACH_AFI_SAFI (afi, safi) {
6773
0
        filter = &group->conf->filter[afi][safi];
6774
6775
0
        for (direct = FILTER_IN; direct < FILTER_MAX;
6776
0
             direct++) {
6777
0
          if (filter->dlist[direct].name)
6778
0
            filter->dlist[direct]
6779
0
              .alist = access_list_lookup(
6780
0
              afi,
6781
0
              filter->dlist[direct]
6782
0
                .name);
6783
0
          else
6784
0
            filter->dlist[direct].alist =
6785
0
              NULL;
6786
0
        }
6787
0
      }
6788
0
    }
6789
0
#ifdef ENABLE_BGP_VNC
6790
0
    vnc_prefix_list_update(bgp);
6791
0
#endif
6792
0
  }
6793
0
}
6794
6795
/* Set prefix list to the peer. */
6796
int peer_prefix_list_set(struct peer *peer, afi_t afi, safi_t safi, int direct,
6797
       const char *name)
6798
0
{
6799
0
  struct peer *member;
6800
0
  struct bgp_filter *filter;
6801
0
  struct listnode *node, *nnode;
6802
6803
0
  if (direct != FILTER_IN && direct != FILTER_OUT)
6804
0
    return BGP_ERR_INVALID_VALUE;
6805
6806
  /* Set configuration on peer. */
6807
0
  filter = &peer->filter[afi][safi];
6808
0
  if (filter->dlist[direct].name)
6809
0
    return BGP_ERR_PEER_FILTER_CONFLICT;
6810
0
  if (filter->plist[direct].name)
6811
0
    XFREE(MTYPE_BGP_FILTER_NAME, filter->plist[direct].name);
6812
0
  filter->plist[direct].name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
6813
0
  filter->plist[direct].plist = prefix_list_lookup(afi, name);
6814
6815
  /* Check if handling a regular peer. */
6816
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6817
    /* Set override-flag and process peer route updates. */
6818
0
    SET_FLAG(peer->filter_override[afi][safi][direct],
6819
0
       PEER_FT_PREFIX_LIST);
6820
0
    peer_on_policy_change(peer, afi, safi,
6821
0
              (direct == FILTER_OUT) ? 1 : 0);
6822
6823
    /* Skip peer-group mechanics for regular peers. */
6824
0
    return 0;
6825
0
  }
6826
6827
  /*
6828
   * Set configuration on all peer-group members, unless they are
6829
   * explicitly overriding peer-group configuration.
6830
   */
6831
0
  for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
6832
    /* Skip peers with overridden configuration. */
6833
0
    if (CHECK_FLAG(member->filter_override[afi][safi][direct],
6834
0
             PEER_FT_PREFIX_LIST))
6835
0
      continue;
6836
6837
    /* Set configuration on peer-group member. */
6838
0
    filter = &member->filter[afi][safi];
6839
0
    if (filter->plist[direct].name)
6840
0
      XFREE(MTYPE_BGP_FILTER_NAME,
6841
0
            filter->plist[direct].name);
6842
0
    filter->plist[direct].name =
6843
0
      XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
6844
0
    filter->plist[direct].plist = prefix_list_lookup(afi, name);
6845
6846
    /* Process peer route updates. */
6847
0
    peer_on_policy_change(member, afi, safi,
6848
0
              (direct == FILTER_OUT) ? 1 : 0);
6849
0
  }
6850
6851
0
  return 0;
6852
0
}
6853
6854
int peer_prefix_list_unset(struct peer *peer, afi_t afi, safi_t safi,
6855
         int direct)
6856
0
{
6857
0
  struct peer *member;
6858
0
  struct bgp_filter *filter;
6859
0
  struct listnode *node, *nnode;
6860
6861
0
  if (direct != FILTER_IN && direct != FILTER_OUT)
6862
0
    return BGP_ERR_INVALID_VALUE;
6863
6864
  /* Unset override-flag unconditionally. */
6865
0
  UNSET_FLAG(peer->filter_override[afi][safi][direct],
6866
0
       PEER_FT_PREFIX_LIST);
6867
6868
  /* Inherit configuration from peer-group if peer is member. */
6869
0
  if (peer_group_active(peer)) {
6870
0
    PEER_STR_ATTR_INHERIT(peer, peer->group,
6871
0
              filter[afi][safi].plist[direct].name,
6872
0
              MTYPE_BGP_FILTER_NAME);
6873
0
    PEER_ATTR_INHERIT(peer, peer->group,
6874
0
          filter[afi][safi].plist[direct].plist);
6875
0
  } else {
6876
    /* Otherwise remove configuration from peer. */
6877
0
    filter = &peer->filter[afi][safi];
6878
0
    if (filter->plist[direct].name)
6879
0
      XFREE(MTYPE_BGP_FILTER_NAME,
6880
0
            filter->plist[direct].name);
6881
0
    filter->plist[direct].name = NULL;
6882
0
    filter->plist[direct].plist = NULL;
6883
0
  }
6884
6885
  /* Check if handling a regular peer. */
6886
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6887
    /* Process peer route updates. */
6888
0
    peer_on_policy_change(peer, afi, safi,
6889
0
              (direct == FILTER_OUT) ? 1 : 0);
6890
6891
    /* Skip peer-group mechanics for regular peers. */
6892
0
    return 0;
6893
0
  }
6894
6895
  /*
6896
   * Remove configuration on all peer-group members, unless they are
6897
   * explicitly overriding peer-group configuration.
6898
   */
6899
0
  for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
6900
    /* Skip peers with overridden configuration. */
6901
0
    if (CHECK_FLAG(member->filter_override[afi][safi][direct],
6902
0
             PEER_FT_PREFIX_LIST))
6903
0
      continue;
6904
6905
    /* Remove configuration on peer-group member. */
6906
0
    filter = &member->filter[afi][safi];
6907
0
    if (filter->plist[direct].name)
6908
0
      XFREE(MTYPE_BGP_FILTER_NAME,
6909
0
            filter->plist[direct].name);
6910
0
    filter->plist[direct].name = NULL;
6911
0
    filter->plist[direct].plist = NULL;
6912
6913
    /* Process peer route updates. */
6914
0
    peer_on_policy_change(member, afi, safi,
6915
0
              (direct == FILTER_OUT) ? 1 : 0);
6916
0
  }
6917
6918
0
  return 0;
6919
0
}
6920
6921
/* Update prefix-list list. */
6922
static void peer_prefix_list_update(struct prefix_list *plist)
6923
0
{
6924
0
  struct listnode *mnode, *mnnode;
6925
0
  struct listnode *node, *nnode;
6926
0
  struct bgp *bgp;
6927
0
  struct peer *peer;
6928
0
  struct peer_group *group;
6929
0
  struct bgp_filter *filter;
6930
0
  afi_t afi;
6931
0
  safi_t safi;
6932
0
  int direct;
6933
6934
0
  for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
6935
6936
    /*
6937
     * Update the prefix-list on update groups.
6938
     */
6939
0
    update_group_policy_update(
6940
0
      bgp, BGP_POLICY_PREFIX_LIST,
6941
0
      plist ? prefix_list_name(plist) : NULL, true, 0);
6942
6943
0
    for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
6944
0
      FOREACH_AFI_SAFI (afi, safi) {
6945
0
        filter = &peer->filter[afi][safi];
6946
6947
0
        for (direct = FILTER_IN; direct < FILTER_MAX;
6948
0
             direct++) {
6949
0
          if (filter->plist[direct].name)
6950
0
            filter->plist[direct]
6951
0
              .plist = prefix_list_lookup(
6952
0
              afi,
6953
0
              filter->plist[direct]
6954
0
                .name);
6955
0
          else
6956
0
            filter->plist[direct].plist =
6957
0
              NULL;
6958
0
        }
6959
6960
        /* If we touch prefix-list, we need to process
6961
         * new updates. This is important for ORF to
6962
         * work correctly.
6963
         */
6964
0
        if (CHECK_FLAG(peer->af_cap[afi][safi],
6965
0
                 PEER_CAP_ORF_PREFIX_SM_ADV) &&
6966
0
            (CHECK_FLAG(peer->af_cap[afi][safi],
6967
0
            PEER_CAP_ORF_PREFIX_RM_RCV) ||
6968
0
             CHECK_FLAG(
6969
0
               peer->af_cap[afi][safi],
6970
0
               PEER_CAP_ORF_PREFIX_RM_OLD_RCV)))
6971
0
          peer_clear_soft(
6972
0
            peer, afi, safi,
6973
0
            BGP_CLEAR_SOFT_IN_ORF_PREFIX);
6974
0
      }
6975
0
    }
6976
0
    for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) {
6977
0
      FOREACH_AFI_SAFI (afi, safi) {
6978
0
        filter = &group->conf->filter[afi][safi];
6979
6980
0
        for (direct = FILTER_IN; direct < FILTER_MAX;
6981
0
             direct++) {
6982
0
          if (filter->plist[direct].name)
6983
0
            filter->plist[direct]
6984
0
              .plist = prefix_list_lookup(
6985
0
              afi,
6986
0
              filter->plist[direct]
6987
0
                .name);
6988
0
          else
6989
0
            filter->plist[direct].plist =
6990
0
              NULL;
6991
0
        }
6992
0
      }
6993
0
    }
6994
0
  }
6995
0
}
6996
6997
int peer_aslist_set(struct peer *peer, afi_t afi, safi_t safi, int direct,
6998
        const char *name)
6999
0
{
7000
0
  struct peer *member;
7001
0
  struct bgp_filter *filter;
7002
0
  struct listnode *node, *nnode;
7003
7004
0
  if (direct != FILTER_IN && direct != FILTER_OUT)
7005
0
    return BGP_ERR_INVALID_VALUE;
7006
7007
  /* Set configuration on peer. */
7008
0
  filter = &peer->filter[afi][safi];
7009
0
  if (filter->aslist[direct].name)
7010
0
    XFREE(MTYPE_BGP_FILTER_NAME, filter->aslist[direct].name);
7011
0
  filter->aslist[direct].name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
7012
0
  filter->aslist[direct].aslist = as_list_lookup(name);
7013
7014
  /* Check if handling a regular peer. */
7015
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
7016
    /* Set override-flag and process peer route updates. */
7017
0
    SET_FLAG(peer->filter_override[afi][safi][direct],
7018
0
       PEER_FT_FILTER_LIST);
7019
0
    peer_on_policy_change(peer, afi, safi,
7020
0
              (direct == FILTER_OUT) ? 1 : 0);
7021
7022
    /* Skip peer-group mechanics for regular peers. */
7023
0
    return 0;
7024
0
  }
7025
7026
  /*
7027
   * Set configuration on all peer-group members, unless they are
7028
   * explicitly overriding peer-group configuration.
7029
   */
7030
0
  for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
7031
    /* Skip peers with overridden configuration. */
7032
0
    if (CHECK_FLAG(member->filter_override[afi][safi][direct],
7033
0
             PEER_FT_FILTER_LIST))
7034
0
      continue;
7035
7036
    /* Set configuration on peer-group member. */
7037
0
    filter = &member->filter[afi][safi];
7038
0
    if (filter->aslist[direct].name)
7039
0
      XFREE(MTYPE_BGP_FILTER_NAME,
7040
0
            filter->aslist[direct].name);
7041
0
    filter->aslist[direct].name =
7042
0
      XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
7043
0
    filter->aslist[direct].aslist = as_list_lookup(name);
7044
7045
    /* Process peer route updates. */
7046
0
    peer_on_policy_change(member, afi, safi,
7047
0
              (direct == FILTER_OUT) ? 1 : 0);
7048
0
  }
7049
7050
0
  return 0;
7051
0
}
7052
7053
int peer_aslist_unset(struct peer *peer, afi_t afi, safi_t safi, int direct)
7054
0
{
7055
0
  struct peer *member;
7056
0
  struct bgp_filter *filter;
7057
0
  struct listnode *node, *nnode;
7058
7059
0
  if (direct != FILTER_IN && direct != FILTER_OUT)
7060
0
    return BGP_ERR_INVALID_VALUE;
7061
7062
  /* Unset override-flag unconditionally. */
7063
0
  UNSET_FLAG(peer->filter_override[afi][safi][direct],
7064
0
       PEER_FT_FILTER_LIST);
7065
7066
  /* Inherit configuration from peer-group if peer is member. */
7067
0
  if (peer_group_active(peer)) {
7068
0
    PEER_STR_ATTR_INHERIT(peer, peer->group,
7069
0
              filter[afi][safi].aslist[direct].name,
7070
0
              MTYPE_BGP_FILTER_NAME);
7071
0
    PEER_ATTR_INHERIT(peer, peer->group,
7072
0
          filter[afi][safi].aslist[direct].aslist);
7073
0
  } else {
7074
    /* Otherwise remove configuration from peer. */
7075
0
    filter = &peer->filter[afi][safi];
7076
0
    if (filter->aslist[direct].name)
7077
0
      XFREE(MTYPE_BGP_FILTER_NAME,
7078
0
            filter->aslist[direct].name);
7079
0
    filter->aslist[direct].name = NULL;
7080
0
    filter->aslist[direct].aslist = NULL;
7081
0
  }
7082
7083
  /* Check if handling a regular peer. */
7084
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
7085
    /* Process peer route updates. */
7086
0
    peer_on_policy_change(peer, afi, safi,
7087
0
              (direct == FILTER_OUT) ? 1 : 0);
7088
7089
    /* Skip peer-group mechanics for regular peers. */
7090
0
    return 0;
7091
0
  }
7092
7093
  /*
7094
   * Remove configuration on all peer-group members, unless they are
7095
   * explicitly overriding peer-group configuration.
7096
   */
7097
0
  for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
7098
    /* Skip peers with overridden configuration. */
7099
0
    if (CHECK_FLAG(member->filter_override[afi][safi][direct],
7100
0
             PEER_FT_FILTER_LIST))
7101
0
      continue;
7102
7103
    /* Remove configuration on peer-group member. */
7104
0
    filter = &member->filter[afi][safi];
7105
0
    if (filter->aslist[direct].name)
7106
0
      XFREE(MTYPE_BGP_FILTER_NAME,
7107
0
            filter->aslist[direct].name);
7108
0
    filter->aslist[direct].name = NULL;
7109
0
    filter->aslist[direct].aslist = NULL;
7110
7111
    /* Process peer route updates. */
7112
0
    peer_on_policy_change(member, afi, safi,
7113
0
              (direct == FILTER_OUT) ? 1 : 0);
7114
0
  }
7115
7116
0
  return 0;
7117
0
}
7118
7119
static void peer_aslist_update(const char *aslist_name)
7120
0
{
7121
0
  afi_t afi;
7122
0
  safi_t safi;
7123
0
  int direct;
7124
0
  struct listnode *mnode, *mnnode;
7125
0
  struct listnode *node, *nnode;
7126
0
  struct bgp *bgp;
7127
0
  struct peer *peer;
7128
0
  struct peer_group *group;
7129
0
  struct bgp_filter *filter;
7130
7131
0
  for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
7132
0
    update_group_policy_update(bgp, BGP_POLICY_FILTER_LIST,
7133
0
             aslist_name, true, 0);
7134
7135
0
    for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
7136
0
      FOREACH_AFI_SAFI (afi, safi) {
7137
0
        filter = &peer->filter[afi][safi];
7138
7139
0
        for (direct = FILTER_IN; direct < FILTER_MAX;
7140
0
             direct++) {
7141
0
          if (filter->aslist[direct].name)
7142
0
            filter->aslist[direct]
7143
0
              .aslist = as_list_lookup(
7144
0
              filter->aslist[direct]
7145
0
                .name);
7146
0
          else
7147
0
            filter->aslist[direct].aslist =
7148
0
              NULL;
7149
0
        }
7150
0
      }
7151
0
    }
7152
0
    for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) {
7153
0
      FOREACH_AFI_SAFI (afi, safi) {
7154
0
        filter = &group->conf->filter[afi][safi];
7155
7156
0
        for (direct = FILTER_IN; direct < FILTER_MAX;
7157
0
             direct++) {
7158
0
          if (filter->aslist[direct].name)
7159
0
            filter->aslist[direct]
7160
0
              .aslist = as_list_lookup(
7161
0
              filter->aslist[direct]
7162
0
                .name);
7163
0
          else
7164
0
            filter->aslist[direct].aslist =
7165
0
              NULL;
7166
0
        }
7167
0
      }
7168
0
    }
7169
0
  }
7170
0
}
7171
7172
static void peer_aslist_add(char *aslist_name)
7173
0
{
7174
0
  peer_aslist_update(aslist_name);
7175
0
  route_map_notify_dependencies(aslist_name, RMAP_EVENT_ASLIST_ADDED);
7176
0
}
7177
7178
static void peer_aslist_del(const char *aslist_name)
7179
0
{
7180
0
  peer_aslist_update(aslist_name);
7181
0
  route_map_notify_dependencies(aslist_name, RMAP_EVENT_ASLIST_DELETED);
7182
0
}
7183
7184
7185
int peer_route_map_set(struct peer *peer, afi_t afi, safi_t safi, int direct,
7186
           const char *name, struct route_map *route_map)
7187
0
{
7188
0
  struct peer *member;
7189
0
  struct bgp_filter *filter;
7190
0
  struct listnode *node, *nnode;
7191
0
  struct route_map *map = NULL;
7192
7193
0
  if (direct != RMAP_IN && direct != RMAP_OUT)
7194
0
    return BGP_ERR_INVALID_VALUE;
7195
7196
  /* Set configuration on peer. */
7197
0
  filter = &peer->filter[afi][safi];
7198
0
  if (filter->map[direct].name) {
7199
    /* If the neighbor is configured with the same route-map
7200
     * again then, ignore the duplicate configuration.
7201
     */
7202
0
    if (strcmp(filter->map[direct].name, name) == 0)
7203
0
      return 0;
7204
7205
0
    map = route_map_lookup_by_name(filter->map[direct].name);
7206
0
    XFREE(MTYPE_BGP_FILTER_NAME, filter->map[direct].name);
7207
0
  }
7208
0
  route_map_counter_decrement(map);
7209
0
  filter->map[direct].name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
7210
0
  filter->map[direct].map = route_map;
7211
0
  route_map_counter_increment(route_map);
7212
7213
  /* Check if handling a regular peer. */
7214
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
7215
    /* Set override-flag and process peer route updates. */
7216
0
    SET_FLAG(peer->filter_override[afi][safi][direct],
7217
0
       PEER_FT_ROUTE_MAP);
7218
0
    peer_on_policy_change(peer, afi, safi,
7219
0
              (direct == RMAP_OUT) ? 1 : 0);
7220
7221
    /* Skip peer-group mechanics for regular peers. */
7222
0
    return 0;
7223
0
  }
7224
7225
  /*
7226
   * Set configuration on all peer-group members, unless they are
7227
   * explicitly overriding peer-group configuration.
7228
   */
7229
0
  for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
7230
0
    map = NULL;
7231
    /* Skip peers with overridden configuration. */
7232
0
    if (CHECK_FLAG(member->filter_override[afi][safi][direct],
7233
0
             PEER_FT_ROUTE_MAP))
7234
0
      continue;
7235
7236
    /* Set configuration on peer-group member. */
7237
0
    filter = &member->filter[afi][safi];
7238
0
    if (filter->map[direct].name) {
7239
0
      map = route_map_lookup_by_name(filter->map[direct].name);
7240
0
      XFREE(MTYPE_BGP_FILTER_NAME, filter->map[direct].name);
7241
0
    }
7242
0
    route_map_counter_decrement(map);
7243
0
    filter->map[direct].name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
7244
0
    filter->map[direct].map = route_map;
7245
0
    route_map_counter_increment(route_map);
7246
7247
    /* Process peer route updates. */
7248
0
    peer_on_policy_change(member, afi, safi,
7249
0
              (direct == RMAP_OUT) ? 1 : 0);
7250
0
  }
7251
0
  return 0;
7252
0
}
7253
7254
/* Unset route-map from the peer. */
7255
int peer_route_map_unset(struct peer *peer, afi_t afi, safi_t safi, int direct)
7256
0
{
7257
0
  struct peer *member;
7258
0
  struct bgp_filter *filter;
7259
0
  struct listnode *node, *nnode;
7260
7261
0
  if (direct != RMAP_IN && direct != RMAP_OUT)
7262
0
    return BGP_ERR_INVALID_VALUE;
7263
7264
  /* Unset override-flag unconditionally. */
7265
0
  UNSET_FLAG(peer->filter_override[afi][safi][direct], PEER_FT_ROUTE_MAP);
7266
7267
  /* Inherit configuration from peer-group if peer is member. */
7268
0
  if (peer_group_active(peer)) {
7269
0
    PEER_STR_ATTR_INHERIT(peer, peer->group,
7270
0
              filter[afi][safi].map[direct].name,
7271
0
              MTYPE_BGP_FILTER_NAME);
7272
0
    PEER_ATTR_INHERIT(peer, peer->group,
7273
0
          filter[afi][safi].map[direct].map);
7274
0
  } else {
7275
0
    struct route_map *map = NULL;
7276
7277
    /* Otherwise remove configuration from peer. */
7278
0
    filter = &peer->filter[afi][safi];
7279
7280
0
    if (filter->map[direct].name) {
7281
0
      map = route_map_lookup_by_name(filter->map[direct].name);
7282
0
      XFREE(MTYPE_BGP_FILTER_NAME, filter->map[direct].name);
7283
0
    }
7284
0
    route_map_counter_decrement(map);
7285
0
    filter->map[direct].name = NULL;
7286
0
    filter->map[direct].map = NULL;
7287
0
  }
7288
7289
  /* Check if handling a regular peer. */
7290
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
7291
    /* Process peer route updates. */
7292
0
    peer_on_policy_change(peer, afi, safi,
7293
0
              (direct == RMAP_OUT) ? 1 : 0);
7294
7295
    /* Skip peer-group mechanics for regular peers. */
7296
0
    return 0;
7297
0
  }
7298
7299
  /*
7300
   * Remove configuration on all peer-group members, unless they are
7301
   * explicitly overriding peer-group configuration.
7302
   */
7303
0
  for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
7304
0
    struct route_map *map;
7305
7306
0
    map = NULL;
7307
7308
    /* Skip peers with overridden configuration. */
7309
0
    if (CHECK_FLAG(member->filter_override[afi][safi][direct],
7310
0
             PEER_FT_ROUTE_MAP))
7311
0
      continue;
7312
7313
    /* Remove configuration on peer-group member. */
7314
0
    filter = &member->filter[afi][safi];
7315
0
    if (filter->map[direct].name) {
7316
0
      map = route_map_lookup_by_name(filter->map[direct].name);
7317
0
      XFREE(MTYPE_BGP_FILTER_NAME, filter->map[direct].name);
7318
0
    }
7319
0
    route_map_counter_decrement(map);
7320
0
    filter->map[direct].name = NULL;
7321
0
    filter->map[direct].map = NULL;
7322
7323
    /* Process peer route updates. */
7324
0
    peer_on_policy_change(member, afi, safi,
7325
0
              (direct == RMAP_OUT) ? 1 : 0);
7326
0
  }
7327
7328
0
  return 0;
7329
0
}
7330
7331
/* Set unsuppress-map to the peer. */
7332
int peer_unsuppress_map_set(struct peer *peer, afi_t afi, safi_t safi,
7333
          const char *name, struct route_map *route_map)
7334
0
{
7335
0
  struct peer *member;
7336
0
  struct bgp_filter *filter;
7337
0
  struct listnode *node, *nnode;
7338
7339
  /* Set configuration on peer. */
7340
0
  filter = &peer->filter[afi][safi];
7341
0
  if (filter->usmap.name)
7342
0
    XFREE(MTYPE_BGP_FILTER_NAME, filter->usmap.name);
7343
0
  route_map_counter_decrement(filter->usmap.map);
7344
0
  filter->usmap.name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
7345
0
  filter->usmap.map = route_map;
7346
0
  route_map_counter_increment(route_map);
7347
7348
  /* Check if handling a regular peer. */
7349
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
7350
    /* Set override-flag and process peer route updates. */
7351
0
    SET_FLAG(peer->filter_override[afi][safi][0],
7352
0
       PEER_FT_UNSUPPRESS_MAP);
7353
0
    peer_on_policy_change(peer, afi, safi, 1);
7354
7355
    /* Skip peer-group mechanics for regular peers. */
7356
0
    return 0;
7357
0
  }
7358
7359
  /*
7360
   * Set configuration on all peer-group members, unless they are
7361
   * explicitly overriding peer-group configuration.
7362
   */
7363
0
  for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
7364
0
    struct route_map *map;
7365
7366
0
    map = NULL;
7367
7368
    /* Skip peers with overridden configuration. */
7369
0
    if (CHECK_FLAG(member->filter_override[afi][safi][0],
7370
0
             PEER_FT_UNSUPPRESS_MAP))
7371
0
      continue;
7372
7373
    /* Set configuration on peer-group member. */
7374
0
    filter = &member->filter[afi][safi];
7375
0
    if (filter->usmap.name) {
7376
0
      map = route_map_lookup_by_name(filter->usmap.name);
7377
0
      XFREE(MTYPE_BGP_FILTER_NAME, filter->usmap.name);
7378
0
    }
7379
0
    route_map_counter_decrement(map);
7380
0
    filter->usmap.name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
7381
0
    filter->usmap.map = route_map;
7382
0
    route_map_counter_increment(route_map);
7383
7384
    /* Process peer route updates. */
7385
0
    peer_on_policy_change(member, afi, safi, 1);
7386
0
  }
7387
7388
0
  return 0;
7389
0
}
7390
7391
/* Unset route-map from the peer. */
7392
int peer_unsuppress_map_unset(struct peer *peer, afi_t afi, safi_t safi)
7393
0
{
7394
0
  struct peer *member;
7395
0
  struct bgp_filter *filter;
7396
0
  struct listnode *node, *nnode;
7397
7398
  /* Unset override-flag unconditionally. */
7399
0
  UNSET_FLAG(peer->filter_override[afi][safi][0], PEER_FT_UNSUPPRESS_MAP);
7400
7401
  /* Inherit configuration from peer-group if peer is member. */
7402
0
  if (peer_group_active(peer)) {
7403
0
    PEER_STR_ATTR_INHERIT(peer, peer->group,
7404
0
              filter[afi][safi].usmap.name,
7405
0
              MTYPE_BGP_FILTER_NAME);
7406
0
    PEER_ATTR_INHERIT(peer, peer->group,
7407
0
          filter[afi][safi].usmap.map);
7408
0
  } else {
7409
0
    struct route_map *map = NULL;
7410
7411
    /* Otherwise remove configuration from peer. */
7412
0
    filter = &peer->filter[afi][safi];
7413
0
    if (filter->usmap.name) {
7414
0
      map = route_map_lookup_by_name(filter->usmap.name);
7415
0
      XFREE(MTYPE_BGP_FILTER_NAME, filter->usmap.name);
7416
0
    }
7417
0
    route_map_counter_decrement(map);
7418
0
    filter->usmap.name = NULL;
7419
0
    filter->usmap.map = NULL;
7420
0
  }
7421
7422
  /* Check if handling a regular peer. */
7423
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
7424
    /* Process peer route updates. */
7425
0
    peer_on_policy_change(peer, afi, safi, 1);
7426
7427
    /* Skip peer-group mechanics for regular peers. */
7428
0
    return 0;
7429
0
  }
7430
7431
  /*
7432
   * Remove configuration on all peer-group members, unless they are
7433
   * explicitly overriding peer-group configuration.
7434
   */
7435
0
  for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
7436
0
    struct route_map *map;
7437
7438
0
    map = NULL;
7439
7440
    /* Skip peers with overridden configuration. */
7441
0
    if (CHECK_FLAG(member->filter_override[afi][safi][0],
7442
0
             PEER_FT_UNSUPPRESS_MAP))
7443
0
      continue;
7444
7445
    /* Remove configuration on peer-group member. */
7446
0
    filter = &member->filter[afi][safi];
7447
0
    if (filter->usmap.name) {
7448
0
      map = route_map_lookup_by_name(filter->usmap.name);
7449
0
      XFREE(MTYPE_BGP_FILTER_NAME, filter->usmap.name);
7450
0
    }
7451
0
    route_map_counter_decrement(map);
7452
0
    filter->usmap.name = NULL;
7453
0
    filter->usmap.map = NULL;
7454
7455
    /* Process peer route updates. */
7456
0
    peer_on_policy_change(member, afi, safi, 1);
7457
0
  }
7458
7459
0
  return 0;
7460
0
}
7461
7462
static bool peer_maximum_prefix_clear_overflow(struct peer *peer)
7463
0
{
7464
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
7465
0
    return false;
7466
7467
0
  UNSET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
7468
0
  if (peer->t_pmax_restart) {
7469
0
    EVENT_OFF(peer->t_pmax_restart);
7470
0
    if (bgp_debug_neighbor_events(peer))
7471
0
      zlog_debug(
7472
0
        "%pBP Maximum-prefix restart timer cancelled",
7473
0
        peer);
7474
0
  }
7475
0
  BGP_EVENT_ADD(peer, BGP_Start);
7476
0
  return true;
7477
0
}
7478
7479
int peer_maximum_prefix_set(struct peer *peer, afi_t afi, safi_t safi,
7480
          uint32_t max, uint8_t threshold, int warning,
7481
          uint16_t restart, bool force)
7482
0
{
7483
0
  struct peer *member;
7484
0
  struct listnode *node, *nnode;
7485
7486
  /* Set flags and configuration on peer. */
7487
0
  peer_af_flag_set(peer, afi, safi, PEER_FLAG_MAX_PREFIX);
7488
7489
0
  if (force)
7490
0
    peer_af_flag_set(peer, afi, safi, PEER_FLAG_MAX_PREFIX_FORCE);
7491
0
  else
7492
0
    peer_af_flag_unset(peer, afi, safi, PEER_FLAG_MAX_PREFIX_FORCE);
7493
7494
0
  if (warning)
7495
0
    peer_af_flag_set(peer, afi, safi, PEER_FLAG_MAX_PREFIX_WARNING);
7496
0
  else
7497
0
    peer_af_flag_unset(peer, afi, safi,
7498
0
           PEER_FLAG_MAX_PREFIX_WARNING);
7499
7500
0
  peer->pmax[afi][safi] = max;
7501
0
  peer->pmax_threshold[afi][safi] = threshold;
7502
0
  peer->pmax_restart[afi][safi] = restart;
7503
7504
  /* Check if handling a regular peer. */
7505
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
7506
    /* Re-check if peer violates maximum-prefix. */
7507
0
    if ((peer_established(peer)) && (peer->afc[afi][safi]))
7508
0
      bgp_maximum_prefix_overflow(peer, afi, safi, 1);
7509
7510
    /* Skip peer-group mechanics for regular peers. */
7511
0
    return 0;
7512
0
  }
7513
7514
  /*
7515
   * Set flags and configuration on all peer-group members, unless they
7516
   * are explicitly overriding peer-group configuration.
7517
   */
7518
0
  for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
7519
    /* Skip peers with overridden configuration. */
7520
0
    if (CHECK_FLAG(member->af_flags_override[afi][safi],
7521
0
             PEER_FLAG_MAX_PREFIX))
7522
0
      continue;
7523
7524
    /* Set flag and configuration on peer-group member. */
7525
0
    member->pmax[afi][safi] = max;
7526
0
    member->pmax_threshold[afi][safi] = threshold;
7527
0
    member->pmax_restart[afi][safi] = restart;
7528
7529
0
    if (force)
7530
0
      SET_FLAG(member->af_flags[afi][safi],
7531
0
         PEER_FLAG_MAX_PREFIX_FORCE);
7532
0
    else
7533
0
      UNSET_FLAG(member->af_flags[afi][safi],
7534
0
           PEER_FLAG_MAX_PREFIX_FORCE);
7535
7536
0
    if (warning)
7537
0
      SET_FLAG(member->af_flags[afi][safi],
7538
0
         PEER_FLAG_MAX_PREFIX_WARNING);
7539
0
    else
7540
0
      UNSET_FLAG(member->af_flags[afi][safi],
7541
0
           PEER_FLAG_MAX_PREFIX_WARNING);
7542
7543
    /* Re-check if peer violates maximum-prefix. */
7544
0
    if ((peer_established(member)) && (member->afc[afi][safi]))
7545
0
      bgp_maximum_prefix_overflow(member, afi, safi, 1);
7546
0
  }
7547
7548
0
  return 0;
7549
0
}
7550
7551
int peer_maximum_prefix_unset(struct peer *peer, afi_t afi, safi_t safi)
7552
0
{
7553
  /* Inherit configuration from peer-group if peer is member. */
7554
0
  if (peer_group_active(peer)) {
7555
0
    peer_af_flag_inherit(peer, afi, safi, PEER_FLAG_MAX_PREFIX);
7556
0
    peer_af_flag_inherit(peer, afi, safi,
7557
0
             PEER_FLAG_MAX_PREFIX_FORCE);
7558
0
    peer_af_flag_inherit(peer, afi, safi,
7559
0
             PEER_FLAG_MAX_PREFIX_WARNING);
7560
0
    PEER_ATTR_INHERIT(peer, peer->group, pmax[afi][safi]);
7561
0
    PEER_ATTR_INHERIT(peer, peer->group, pmax_threshold[afi][safi]);
7562
0
    PEER_ATTR_INHERIT(peer, peer->group, pmax_restart[afi][safi]);
7563
7564
0
    return 0;
7565
0
  }
7566
7567
  /* Remove flags and configuration from peer. */
7568
0
  peer_af_flag_unset(peer, afi, safi, PEER_FLAG_MAX_PREFIX);
7569
0
  peer_af_flag_unset(peer, afi, safi, PEER_FLAG_MAX_PREFIX_FORCE);
7570
0
  peer_af_flag_unset(peer, afi, safi, PEER_FLAG_MAX_PREFIX_WARNING);
7571
0
  peer->pmax[afi][safi] = 0;
7572
0
  peer->pmax_threshold[afi][safi] = 0;
7573
0
  peer->pmax_restart[afi][safi] = 0;
7574
7575
  /*
7576
   * Remove flags and configuration from all peer-group members, unless
7577
   * they are explicitly overriding peer-group configuration.
7578
   */
7579
0
  if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
7580
0
    struct peer *member;
7581
0
    struct listnode *node;
7582
7583
0
    for (ALL_LIST_ELEMENTS_RO(peer->group->peer, node, member)) {
7584
      /* Skip peers with overridden configuration. */
7585
0
      if (CHECK_FLAG(member->af_flags_override[afi][safi],
7586
0
               PEER_FLAG_MAX_PREFIX))
7587
0
        continue;
7588
7589
      /* Remove flag and configuration on peer-group member.
7590
       */
7591
0
      UNSET_FLAG(member->af_flags[afi][safi],
7592
0
           PEER_FLAG_MAX_PREFIX);
7593
0
      UNSET_FLAG(member->af_flags[afi][safi],
7594
0
           PEER_FLAG_MAX_PREFIX_FORCE);
7595
0
      UNSET_FLAG(member->af_flags[afi][safi],
7596
0
           PEER_FLAG_MAX_PREFIX_WARNING);
7597
0
      member->pmax[afi][safi] = 0;
7598
0
      member->pmax_threshold[afi][safi] = 0;
7599
0
      member->pmax_restart[afi][safi] = 0;
7600
7601
0
      peer_maximum_prefix_clear_overflow(member);
7602
0
    }
7603
0
  } else {
7604
0
    peer_maximum_prefix_clear_overflow(peer);
7605
0
  }
7606
7607
0
  return 0;
7608
0
}
7609
7610
void peer_maximum_prefix_out_refresh_routes(struct peer *peer, afi_t afi,
7611
              safi_t safi)
7612
0
{
7613
0
  update_group_adjust_peer(peer_af_find(peer, afi, safi));
7614
7615
0
  if (peer_established(peer))
7616
0
    bgp_announce_route(peer, afi, safi, false);
7617
0
}
7618
7619
int peer_maximum_prefix_out_set(struct peer *peer, afi_t afi, safi_t safi,
7620
        uint32_t max)
7621
0
{
7622
0
  struct peer *member;
7623
0
  struct listnode *node, *nnode;
7624
7625
  /* Set flag on peer and peer-group member if any */
7626
0
  peer_af_flag_set(peer, afi, safi, PEER_FLAG_MAX_PREFIX_OUT);
7627
  /* Set configuration on peer. */
7628
0
  peer->pmax_out[afi][safi] = max;
7629
7630
  /* Check if handling a regular peer. */
7631
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
7632
    /* Skip peer-group mechanics for regular peers. */
7633
0
    peer_maximum_prefix_out_refresh_routes(peer, afi, safi);
7634
0
    return 0;
7635
0
  }
7636
7637
  /*
7638
   * Set flag and configuration on all peer-group members, unless they
7639
   * are explicitly overriding peer-group configuration.
7640
   */
7641
0
  for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
7642
    /* Skip peers with overridden configuration. */
7643
0
    if (CHECK_FLAG(member->af_flags_override[afi][safi],
7644
0
             PEER_FLAG_MAX_PREFIX_OUT))
7645
0
      continue;
7646
7647
    /* Set configuration on peer-group member. */
7648
0
    member->pmax_out[afi][safi] = max;
7649
7650
0
    peer_maximum_prefix_out_refresh_routes(member, afi, safi);
7651
0
  }
7652
0
  return 0;
7653
0
}
7654
7655
int peer_maximum_prefix_out_unset(struct peer *peer, afi_t afi, safi_t safi)
7656
0
{
7657
0
  struct peer *member;
7658
0
  struct listnode *node;
7659
  /* Inherit configuration from peer-group if peer is member. */
7660
0
  if (peer_group_active(peer)) {
7661
0
    peer_af_flag_inherit(peer, afi, safi, PEER_FLAG_MAX_PREFIX_OUT);
7662
0
    PEER_ATTR_INHERIT(peer, peer->group, pmax_out[afi][safi]);
7663
7664
0
    peer_maximum_prefix_out_refresh_routes(peer, afi, safi);
7665
0
    return 0;
7666
0
  }
7667
7668
  /* Remove flag and configuration from peer. */
7669
0
  peer_af_flag_unset(peer, afi, safi, PEER_FLAG_MAX_PREFIX_OUT);
7670
0
  peer->pmax_out[afi][safi] = 0;
7671
7672
  /* Check if handling a regular peer. */
7673
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
7674
    /* Skip peer-group mechanics for regular peers. */
7675
0
    peer_maximum_prefix_out_refresh_routes(peer, afi, safi);
7676
0
    return 0;
7677
0
  }
7678
7679
  /*
7680
   * Remove flag and configuration from all peer-group members, unless
7681
   * they are explicitly overriding peer-group configuration.
7682
   */
7683
0
  for (ALL_LIST_ELEMENTS_RO(peer->group->peer, node, member)) {
7684
    /* Skip peers with overridden configuration. */
7685
0
    if (CHECK_FLAG(member->af_flags_override[afi][safi],
7686
0
             PEER_FLAG_MAX_PREFIX_OUT))
7687
0
      continue;
7688
7689
    /* Remove flag and configuration on peer-group member.
7690
     */
7691
0
    UNSET_FLAG(member->af_flags[afi][safi],
7692
0
         PEER_FLAG_MAX_PREFIX_OUT);
7693
0
    member->pmax_out[afi][safi] = 0;
7694
7695
0
    peer_maximum_prefix_out_refresh_routes(member, afi, safi);
7696
0
  }
7697
0
  return 0;
7698
0
}
7699
7700
int is_ebgp_multihop_configured(struct peer *peer)
7701
0
{
7702
0
  struct peer_group *group;
7703
0
  struct listnode *node, *nnode;
7704
0
  struct peer *peer1;
7705
7706
0
  if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
7707
0
    group = peer->group;
7708
0
    if ((peer_sort(peer) != BGP_PEER_IBGP)
7709
0
        && (group->conf->ttl != BGP_DEFAULT_TTL))
7710
0
      return 1;
7711
7712
0
    for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer1)) {
7713
0
      if ((peer_sort(peer1) != BGP_PEER_IBGP)
7714
0
          && (peer1->ttl != BGP_DEFAULT_TTL))
7715
0
        return 1;
7716
0
    }
7717
0
  } else {
7718
0
    if ((peer_sort(peer) != BGP_PEER_IBGP)
7719
0
        && (peer->ttl != BGP_DEFAULT_TTL))
7720
0
      return 1;
7721
0
  }
7722
0
  return 0;
7723
0
}
7724
7725
/* Set # of hops between us and BGP peer. */
7726
int peer_ttl_security_hops_set(struct peer *peer, int gtsm_hops)
7727
0
{
7728
0
  struct peer_group *group;
7729
0
  struct peer *gpeer;
7730
0
  struct listnode *node, *nnode;
7731
0
  int ret;
7732
7733
0
  zlog_debug("%s: set gtsm_hops to %d for %s", __func__, gtsm_hops,
7734
0
       peer->host);
7735
7736
  /* We cannot configure ttl-security hops when ebgp-multihop is already
7737
     set.  For non peer-groups, the check is simple.  For peer-groups,
7738
     it's
7739
     slightly messy, because we need to check both the peer-group
7740
     structure
7741
     and all peer-group members for any trace of ebgp-multihop
7742
     configuration
7743
     before actually applying the ttl-security rules.  Cisco really made a
7744
     mess of this configuration parameter, and OpenBGPD got it right.
7745
  */
7746
7747
0
  if ((peer->gtsm_hops == BGP_GTSM_HOPS_DISABLED)
7748
0
      && (peer->sort != BGP_PEER_IBGP)) {
7749
0
    if (is_ebgp_multihop_configured(peer))
7750
0
      return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
7751
7752
0
    if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
7753
0
      peer->gtsm_hops = gtsm_hops;
7754
7755
      /* Calling ebgp multihop also resets the session.
7756
       * On restart, NHT will get setup correctly as will the
7757
       * min & max ttls on the socket. The return value is
7758
       * irrelevant.
7759
       */
7760
0
      ret = peer_ebgp_multihop_set(peer, MAXTTL);
7761
7762
0
      if (ret != 0)
7763
0
        return ret;
7764
0
    } else {
7765
0
      group = peer->group;
7766
0
      group->conf->gtsm_hops = gtsm_hops;
7767
0
      for (ALL_LIST_ELEMENTS(group->peer, node, nnode,
7768
0
                 gpeer)) {
7769
0
        gpeer->gtsm_hops = group->conf->gtsm_hops;
7770
7771
        /* Calling ebgp multihop also resets the
7772
         * session.
7773
         * On restart, NHT will get setup correctly as
7774
         * will the
7775
         * min & max ttls on the socket. The return
7776
         * value is
7777
         * irrelevant.
7778
         */
7779
0
        peer_ebgp_multihop_set(gpeer, MAXTTL);
7780
0
      }
7781
0
    }
7782
0
  } else {
7783
    /* Post the first gtsm setup or if its ibgp, maxttl setting
7784
     * isn't
7785
     * necessary, just set the minttl.
7786
     */
7787
0
    if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
7788
0
      peer->gtsm_hops = gtsm_hops;
7789
7790
0
      if (peer->fd >= 0)
7791
0
        sockopt_minttl(peer->su.sa.sa_family, peer->fd,
7792
0
                 MAXTTL + 1 - gtsm_hops);
7793
0
      if ((peer->status < Established) && peer->doppelganger
7794
0
          && (peer->doppelganger->fd >= 0))
7795
0
        sockopt_minttl(peer->su.sa.sa_family,
7796
0
                 peer->doppelganger->fd,
7797
0
                 MAXTTL + 1 - gtsm_hops);
7798
0
    } else {
7799
0
      group = peer->group;
7800
0
      group->conf->gtsm_hops = gtsm_hops;
7801
0
      for (ALL_LIST_ELEMENTS(group->peer, node, nnode,
7802
0
                 gpeer)) {
7803
0
        gpeer->gtsm_hops = group->conf->gtsm_hops;
7804
7805
        /* Change setting of existing peer
7806
         *   established then change value (may break
7807
         * connectivity)
7808
         *   not established yet (teardown session and
7809
         * restart)
7810
         *   no session then do nothing (will get
7811
         * handled by next connection)
7812
         */
7813
0
        if (gpeer->fd >= 0
7814
0
            && gpeer->gtsm_hops
7815
0
                 != BGP_GTSM_HOPS_DISABLED)
7816
0
          sockopt_minttl(
7817
0
            gpeer->su.sa.sa_family,
7818
0
            gpeer->fd,
7819
0
            MAXTTL + 1 - gpeer->gtsm_hops);
7820
0
        if ((gpeer->status < Established)
7821
0
            && gpeer->doppelganger
7822
0
            && (gpeer->doppelganger->fd >= 0))
7823
0
          sockopt_minttl(gpeer->su.sa.sa_family,
7824
0
                   gpeer->doppelganger->fd,
7825
0
                   MAXTTL + 1 - gtsm_hops);
7826
0
      }
7827
0
    }
7828
0
  }
7829
7830
0
  return 0;
7831
0
}
7832
7833
int peer_ttl_security_hops_unset(struct peer *peer)
7834
0
{
7835
0
  struct peer_group *group;
7836
0
  struct listnode *node, *nnode;
7837
0
  int ret = 0;
7838
7839
0
  zlog_debug("%s: set gtsm_hops to zero for %s", __func__, peer->host);
7840
7841
  /* if a peer-group member, then reset to peer-group default rather than
7842
   * 0 */
7843
0
  if (peer_group_active(peer))
7844
0
    peer->gtsm_hops = peer->group->conf->gtsm_hops;
7845
0
  else
7846
0
    peer->gtsm_hops = BGP_GTSM_HOPS_DISABLED;
7847
7848
0
  if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
7849
    /* Invoking ebgp_multihop_set will set the TTL back to the
7850
     * original
7851
     * value as well as restting the NHT and such. The session is
7852
     * reset.
7853
     */
7854
0
    if (peer->sort == BGP_PEER_EBGP)
7855
0
      ret = peer_ebgp_multihop_unset(peer);
7856
0
    else {
7857
0
      if (peer->fd >= 0)
7858
0
        sockopt_minttl(peer->su.sa.sa_family, peer->fd,
7859
0
                 0);
7860
7861
0
      if ((peer->status < Established) && peer->doppelganger
7862
0
          && (peer->doppelganger->fd >= 0))
7863
0
        sockopt_minttl(peer->su.sa.sa_family,
7864
0
                 peer->doppelganger->fd, 0);
7865
0
    }
7866
0
  } else {
7867
0
    group = peer->group;
7868
0
    for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
7869
0
      peer->gtsm_hops = BGP_GTSM_HOPS_DISABLED;
7870
0
      if (peer->sort == BGP_PEER_EBGP)
7871
0
        ret = peer_ebgp_multihop_unset(peer);
7872
0
      else {
7873
0
        if (peer->fd >= 0)
7874
0
          sockopt_minttl(peer->su.sa.sa_family,
7875
0
                   peer->fd, 0);
7876
7877
0
        if ((peer->status < Established)
7878
0
            && peer->doppelganger
7879
0
            && (peer->doppelganger->fd >= 0))
7880
0
          sockopt_minttl(peer->su.sa.sa_family,
7881
0
                   peer->doppelganger->fd,
7882
0
                   0);
7883
0
      }
7884
0
    }
7885
0
  }
7886
7887
0
  return ret;
7888
0
}
7889
7890
static void peer_reset_message_stats(struct peer *peer)
7891
0
{
7892
0
  if (peer) {
7893
0
    atomic_store_explicit(&peer->open_in, 0, memory_order_relaxed);
7894
0
    atomic_store_explicit(&peer->open_out, 0, memory_order_relaxed);
7895
0
    atomic_store_explicit(&peer->update_in, 0,
7896
0
              memory_order_relaxed);
7897
0
    atomic_store_explicit(&peer->update_out, 0,
7898
0
              memory_order_relaxed);
7899
0
    atomic_store_explicit(&peer->keepalive_in, 0,
7900
0
              memory_order_relaxed);
7901
0
    atomic_store_explicit(&peer->keepalive_out, 0,
7902
0
              memory_order_relaxed);
7903
0
    atomic_store_explicit(&peer->notify_in, 0,
7904
0
              memory_order_relaxed);
7905
0
    atomic_store_explicit(&peer->notify_out, 0,
7906
0
              memory_order_relaxed);
7907
0
    atomic_store_explicit(&peer->refresh_in, 0,
7908
0
              memory_order_relaxed);
7909
0
    atomic_store_explicit(&peer->refresh_out, 0,
7910
0
              memory_order_relaxed);
7911
0
    atomic_store_explicit(&peer->dynamic_cap_in, 0,
7912
0
              memory_order_relaxed);
7913
0
    atomic_store_explicit(&peer->dynamic_cap_out, 0,
7914
0
              memory_order_relaxed);
7915
0
  }
7916
0
}
7917
7918
/*
7919
 * If peer clear is invoked in a loop for all peers on the BGP instance,
7920
 * it may end up freeing the doppelganger, and if this was the next node
7921
 * to the current node, we would end up accessing the freed next node.
7922
 * Pass along additional parameter which can be updated if next node
7923
 * is freed; only required when walking the peer list on BGP instance.
7924
 */
7925
int peer_clear(struct peer *peer, struct listnode **nnode)
7926
0
{
7927
0
  if (!CHECK_FLAG(peer->flags, PEER_FLAG_SHUTDOWN)
7928
0
      || !CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHUTDOWN)) {
7929
0
    if (peer_maximum_prefix_clear_overflow(peer))
7930
0
      return 0;
7931
7932
0
    peer->v_start = BGP_INIT_START_TIMER;
7933
0
    if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
7934
0
      bgp_notify_send(peer, BGP_NOTIFY_CEASE,
7935
0
          BGP_NOTIFY_CEASE_ADMIN_RESET);
7936
0
    else
7937
0
      bgp_session_reset_safe(peer, nnode);
7938
0
  }
7939
0
  return 0;
7940
0
}
7941
7942
int peer_clear_soft(struct peer *peer, afi_t afi, safi_t safi,
7943
        enum bgp_clear_type stype)
7944
0
{
7945
0
  struct peer_af *paf;
7946
7947
0
  if (!peer_established(peer))
7948
0
    return 0;
7949
7950
0
  if (!peer->afc[afi][safi])
7951
0
    return BGP_ERR_AF_UNCONFIGURED;
7952
7953
0
  peer->rtt = sockopt_tcp_rtt(peer->fd);
7954
7955
0
  if (stype == BGP_CLEAR_SOFT_OUT || stype == BGP_CLEAR_SOFT_BOTH) {
7956
    /* Clear the "neighbor x.x.x.x default-originate" flag */
7957
0
    paf = peer_af_find(peer, afi, safi);
7958
0
    if (paf && paf->subgroup
7959
0
        && CHECK_FLAG(paf->subgroup->sflags,
7960
0
          SUBGRP_STATUS_DEFAULT_ORIGINATE))
7961
0
      UNSET_FLAG(paf->subgroup->sflags,
7962
0
           SUBGRP_STATUS_DEFAULT_ORIGINATE);
7963
7964
0
    bgp_announce_route(peer, afi, safi, false);
7965
0
  }
7966
7967
0
  if (stype == BGP_CLEAR_SOFT_IN_ORF_PREFIX) {
7968
0
    if (CHECK_FLAG(peer->af_cap[afi][safi],
7969
0
             PEER_CAP_ORF_PREFIX_SM_ADV)
7970
0
        && (CHECK_FLAG(peer->af_cap[afi][safi],
7971
0
           PEER_CAP_ORF_PREFIX_RM_RCV)
7972
0
      || CHECK_FLAG(peer->af_cap[afi][safi],
7973
0
              PEER_CAP_ORF_PREFIX_RM_OLD_RCV))) {
7974
0
      struct bgp_filter *filter = &peer->filter[afi][safi];
7975
0
      uint8_t prefix_type;
7976
7977
0
      if (CHECK_FLAG(peer->af_cap[afi][safi],
7978
0
               PEER_CAP_ORF_PREFIX_RM_RCV))
7979
0
        prefix_type = ORF_TYPE_PREFIX;
7980
0
      else
7981
0
        prefix_type = ORF_TYPE_PREFIX_OLD;
7982
7983
0
      if (filter->plist[FILTER_IN].plist) {
7984
0
        if (CHECK_FLAG(peer->af_sflags[afi][safi],
7985
0
                 PEER_STATUS_ORF_PREFIX_SEND))
7986
0
          bgp_route_refresh_send(
7987
0
            peer, afi, safi, prefix_type,
7988
0
            REFRESH_DEFER, 1,
7989
0
            BGP_ROUTE_REFRESH_NORMAL);
7990
0
        bgp_route_refresh_send(
7991
0
          peer, afi, safi, prefix_type,
7992
0
          REFRESH_IMMEDIATE, 0,
7993
0
          BGP_ROUTE_REFRESH_NORMAL);
7994
0
      } else {
7995
0
        if (CHECK_FLAG(peer->af_sflags[afi][safi],
7996
0
                 PEER_STATUS_ORF_PREFIX_SEND))
7997
0
          bgp_route_refresh_send(
7998
0
            peer, afi, safi, prefix_type,
7999
0
            REFRESH_IMMEDIATE, 1,
8000
0
            BGP_ROUTE_REFRESH_NORMAL);
8001
0
        else
8002
0
          bgp_route_refresh_send(
8003
0
            peer, afi, safi, 0, 0, 0,
8004
0
            BGP_ROUTE_REFRESH_NORMAL);
8005
0
      }
8006
0
      return 0;
8007
0
    }
8008
0
  }
8009
8010
0
  if (stype == BGP_CLEAR_SOFT_IN || stype == BGP_CLEAR_SOFT_BOTH
8011
0
      || stype == BGP_CLEAR_SOFT_IN_ORF_PREFIX) {
8012
    /* If neighbor has soft reconfiguration inbound flag.
8013
       Use Adj-RIB-In database. */
8014
0
    if (!bgp_soft_reconfig_in(peer, afi, safi)) {
8015
      /* If neighbor has route refresh capability, send route
8016
         refresh
8017
         message to the peer. */
8018
0
      if (CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_OLD_RCV)
8019
0
          || CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_NEW_RCV))
8020
0
        bgp_route_refresh_send(
8021
0
          peer, afi, safi, 0, 0, 0,
8022
0
          BGP_ROUTE_REFRESH_NORMAL);
8023
0
      else
8024
0
        return BGP_ERR_SOFT_RECONFIG_UNCONFIGURED;
8025
0
    }
8026
0
  }
8027
8028
0
  if (stype == BGP_CLEAR_MESSAGE_STATS)
8029
0
    peer_reset_message_stats(peer);
8030
8031
0
  return 0;
8032
0
}
8033
8034
/* Display peer uptime.*/
8035
char *peer_uptime(time_t uptime2, char *buf, size_t len, bool use_json,
8036
      json_object *json)
8037
0
{
8038
0
  time_t uptime1, epoch_tbuf;
8039
0
  struct tm tm;
8040
8041
  /* If there is no connection has been done before print `never'. */
8042
0
  if (uptime2 == 0) {
8043
0
    if (use_json) {
8044
0
      json_object_string_add(json, "peerUptime", "never");
8045
0
      json_object_int_add(json, "peerUptimeMsec", 0);
8046
0
    } else
8047
0
      snprintf(buf, len, "never");
8048
0
    return buf;
8049
0
  }
8050
8051
  /* Get current time. */
8052
0
  uptime1 = monotime(NULL);
8053
0
  uptime1 -= uptime2;
8054
0
  gmtime_r(&uptime1, &tm);
8055
8056
0
  if (uptime1 < ONE_DAY_SECOND)
8057
0
    snprintf(buf, len, "%02d:%02d:%02d", tm.tm_hour, tm.tm_min,
8058
0
       tm.tm_sec);
8059
0
  else if (uptime1 < ONE_WEEK_SECOND)
8060
0
    snprintf(buf, len, "%dd%02dh%02dm", tm.tm_yday, tm.tm_hour,
8061
0
       tm.tm_min);
8062
0
  else if (uptime1 < ONE_YEAR_SECOND)
8063
0
    snprintf(buf, len, "%02dw%dd%02dh", tm.tm_yday / 7,
8064
0
       tm.tm_yday - ((tm.tm_yday / 7) * 7), tm.tm_hour);
8065
0
  else
8066
0
    snprintf(buf, len, "%02dy%02dw%dd", tm.tm_year - 70,
8067
0
       tm.tm_yday / 7,
8068
0
       tm.tm_yday - ((tm.tm_yday / 7) * 7));
8069
8070
0
  if (use_json) {
8071
0
    epoch_tbuf = time(NULL) - uptime1;
8072
0
    json_object_string_add(json, "peerUptime", buf);
8073
0
    json_object_int_add(json, "peerUptimeMsec", uptime1 * 1000);
8074
0
    json_object_int_add(json, "peerUptimeEstablishedEpoch",
8075
0
            epoch_tbuf);
8076
0
  }
8077
8078
0
  return buf;
8079
0
}
8080
8081
void bgp_master_init(struct event_loop *master, const int buffer_size,
8082
         struct list *addresses)
8083
1
{
8084
1
  qobj_init();
8085
8086
1
  memset(&bgp_master, 0, sizeof(bgp_master));
8087
8088
1
  bm = &bgp_master;
8089
1
  bm->bgp = list_new();
8090
1
  bm->listen_sockets = list_new();
8091
1
  bm->port = BGP_PORT_DEFAULT;
8092
1
  bm->addresses = addresses;
8093
1
  bm->master = master;
8094
1
  bm->start_time = monotime(NULL);
8095
1
  bm->t_rmap_update = NULL;
8096
1
  bm->rmap_update_timer = RMAP_DEFAULT_UPDATE_TIMER;
8097
1
  bm->v_update_delay = BGP_UPDATE_DELAY_DEF;
8098
1
  bm->v_establish_wait = BGP_UPDATE_DELAY_DEF;
8099
1
  bm->terminating = false;
8100
1
  bm->socket_buffer = buffer_size;
8101
1
  bm->wait_for_fib = false;
8102
1
  bm->tcp_dscp = IPTOS_PREC_INTERNETCONTROL;
8103
1
  bm->inq_limit = BM_DEFAULT_Q_LIMIT;
8104
1
  bm->outq_limit = BM_DEFAULT_Q_LIMIT;
8105
8106
1
  bgp_mac_init();
8107
  /* init the rd id space.
8108
     assign 0th index in the bitfield,
8109
     so that we start with id 1
8110
   */
8111
1
  bf_init(bm->rd_idspace, UINT16_MAX);
8112
1
  bf_assign_zero_index(bm->rd_idspace);
8113
8114
  /* mpls label dynamic allocation pool */
8115
1
  bgp_lp_init(bm->master, &bm->labelpool);
8116
8117
1
  bgp_l3nhg_init();
8118
1
  bgp_evpn_mh_init();
8119
1
  QOBJ_REG(bm, bgp_master);
8120
1
}
8121
8122
/*
8123
 * Free up connected routes and interfaces for a BGP instance. Invoked upon
8124
 * instance delete (non-default only) or BGP exit.
8125
 */
8126
static void bgp_if_finish(struct bgp *bgp)
8127
0
{
8128
0
  struct vrf *vrf;
8129
0
  struct interface *ifp;
8130
8131
0
  vrf = bgp_vrf_lookup_by_instance_type(bgp);
8132
8133
0
  if (bgp->inst_type == BGP_INSTANCE_TYPE_VIEW || !vrf)
8134
0
    return;
8135
8136
0
  FOR_ALL_INTERFACES (vrf, ifp) {
8137
0
    struct listnode *c_node, *c_nnode;
8138
0
    struct connected *c;
8139
8140
0
    for (ALL_LIST_ELEMENTS(ifp->connected, c_node, c_nnode, c))
8141
0
      bgp_connected_delete(bgp, c);
8142
0
  }
8143
0
}
8144
8145
static void bgp_viewvrf_autocomplete(vector comps, struct cmd_token *token)
8146
0
{
8147
0
  struct vrf *vrf = NULL;
8148
0
  struct listnode *next;
8149
0
  struct bgp *bgp;
8150
0
8151
0
  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
8152
0
    vector_set(comps, XSTRDUP(MTYPE_COMPLETION, vrf->name));
8153
0
8154
0
  for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, bgp)) {
8155
0
    if (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW)
8156
0
      continue;
8157
0
8158
0
    vector_set(comps, XSTRDUP(MTYPE_COMPLETION, bgp->name));
8159
0
  }
8160
0
}
8161
8162
static void bgp_instasn_autocomplete(vector comps, struct cmd_token *token)
8163
0
{
8164
0
  struct listnode *next, *next2;
8165
0
  struct bgp *bgp, *bgp2;
8166
0
  char buf[ASN_STRING_MAX_SIZE];
8167
0
8168
0
  for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, bgp)) {
8169
0
    /* deduplicate */
8170
0
    for (ALL_LIST_ELEMENTS_RO(bm->bgp, next2, bgp2)) {
8171
0
      if (bgp2->as == bgp->as)
8172
0
        break;
8173
0
      if (bgp2 == bgp)
8174
0
        break;
8175
0
    }
8176
0
    if (bgp2 != bgp)
8177
0
      continue;
8178
0
8179
0
    snprintf(buf, sizeof(buf), "%s", bgp->as_pretty);
8180
0
    vector_set(comps, XSTRDUP(MTYPE_COMPLETION, buf));
8181
0
  }
8182
0
}
8183
8184
static const struct cmd_variable_handler bgp_viewvrf_var_handlers[] = {
8185
  {.tokenname = "VIEWVRFNAME", .completions = bgp_viewvrf_autocomplete},
8186
  {.varname = "instasn", .completions = bgp_instasn_autocomplete},
8187
  {.completions = NULL},
8188
};
8189
8190
struct frr_pthread *bgp_pth_io;
8191
struct frr_pthread *bgp_pth_ka;
8192
8193
static void bgp_pthreads_init(void)
8194
0
{
8195
0
  assert(!bgp_pth_io);
8196
0
  assert(!bgp_pth_ka);
8197
0
8198
0
  struct frr_pthread_attr io = {
8199
0
    .start = frr_pthread_attr_default.start,
8200
0
    .stop = frr_pthread_attr_default.stop,
8201
0
  };
8202
0
  struct frr_pthread_attr ka = {
8203
0
    .start = bgp_keepalives_start,
8204
0
    .stop = bgp_keepalives_stop,
8205
0
  };
8206
0
  bgp_pth_io = frr_pthread_new(&io, "BGP I/O thread", "bgpd_io");
8207
0
  bgp_pth_ka = frr_pthread_new(&ka, "BGP Keepalives thread", "bgpd_ka");
8208
0
}
8209
8210
void bgp_pthreads_run(void)
8211
0
{
8212
0
  frr_pthread_run(bgp_pth_io, NULL);
8213
0
  frr_pthread_run(bgp_pth_ka, NULL);
8214
8215
  /* Wait until threads are ready. */
8216
0
  frr_pthread_wait_running(bgp_pth_io);
8217
0
  frr_pthread_wait_running(bgp_pth_ka);
8218
0
}
8219
8220
void bgp_pthreads_finish(void)
8221
0
{
8222
0
  frr_pthread_stop_all();
8223
0
}
8224
8225
static int peer_unshut_after_cfg(struct bgp *bgp)
8226
0
{
8227
0
  struct listnode *node;
8228
0
  struct peer *peer;
8229
8230
0
  for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer)) {
8231
0
    if (!peer->shut_during_cfg)
8232
0
      continue;
8233
8234
0
    if (bgp_debug_neighbor_events(peer))
8235
0
      zlog_debug("%s: released from config-pending hold",
8236
0
           peer->host);
8237
8238
0
    peer->shut_during_cfg = false;
8239
0
    if (peer_active(peer) && peer->status != Established) {
8240
0
      if (peer->status != Idle)
8241
0
        BGP_EVENT_ADD(peer, BGP_Stop);
8242
0
      BGP_EVENT_ADD(peer, BGP_Start);
8243
0
    }
8244
0
  }
8245
8246
0
  return 0;
8247
0
}
8248
8249
void bgp_init(unsigned short instance)
8250
1
{
8251
1
  hook_register(bgp_config_end, peer_unshut_after_cfg);
8252
8253
  /* allocates some vital data structures used by peer commands in
8254
   * vty_init */
8255
#ifndef FUZZING
8256
  /* pre-init pthreads */
8257
  bgp_pthreads_init();
8258
8259
  /* Init zebra. */
8260
  bgp_zebra_init(bm->master, instance);
8261
#endif
8262
1
#ifdef ENABLE_BGP_VNC
8263
1
  vnc_zebra_init(bm->master);
8264
1
#endif
8265
8266
  /* BGP VTY commands installation.  */
8267
#ifndef FUZZING
8268
  bgp_vty_init();
8269
#endif
8270
8271
  /* BGP inits. */
8272
1
  bgp_attr_init();
8273
1
  bgp_community_alias_init();
8274
#ifndef FUZZING
8275
  bgp_debug_init();
8276
  bgp_dump_init();
8277
#endif
8278
1
  bgp_route_init();
8279
1
  bgp_route_map_init();
8280
#ifndef FUZZING
8281
  bgp_scan_vty_init();
8282
#endif
8283
1
  bgp_mplsvpn_init();
8284
#ifndef FUZZING
8285
#ifdef ENABLE_BGP_VNC
8286
  rfapi_init();
8287
#endif
8288
  bgp_ethernetvpn_init();
8289
  bgp_flowspec_vty_init();
8290
#endif
8291
  /* Access list initialize. */
8292
1
  access_list_init();
8293
1
  access_list_add_hook(peer_distribute_update);
8294
1
  access_list_delete_hook(peer_distribute_update);
8295
8296
  /* Filter list initialize. */
8297
1
  bgp_filter_init();
8298
1
  as_list_add_hook(peer_aslist_add);
8299
1
  as_list_delete_hook(peer_aslist_del);
8300
8301
  /* Prefix list initialize.*/
8302
1
  prefix_list_init();
8303
1
  prefix_list_add_hook(peer_prefix_list_update);
8304
1
  prefix_list_delete_hook(peer_prefix_list_update);
8305
8306
  /* Community list initialize. */
8307
1
  bgp_clist = community_list_init();
8308
8309
1
  bgp_label_per_nexthop_init();
8310
8311
#ifndef FUZZING
8312
  /* BFD init */
8313
  bgp_bfd_init(bm->master);
8314
  bgp_lp_vty_init();
8315
  cmd_variable_handler_register(bgp_viewvrf_var_handlers);
8316
#endif
8317
1
}
8318
8319
void bgp_terminate(void)
8320
0
{
8321
0
  struct bgp *bgp;
8322
0
  struct peer *peer;
8323
0
  struct listnode *node, *nnode;
8324
0
  struct listnode *mnode, *mnnode;
8325
8326
0
  QOBJ_UNREG(bm);
8327
8328
  /* Close the listener sockets first as this prevents peers from
8329
   * attempting
8330
   * to reconnect on receiving the peer unconfig message. In the presence
8331
   * of a large number of peers this will ensure that no peer is left with
8332
   * a dangling connection
8333
   */
8334
8335
0
  bgp_close();
8336
  /* reverse bgp_master_init */
8337
0
  for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
8338
0
    bgp_close_vrf_socket(bgp);
8339
0
    for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
8340
0
      if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)) {
8341
0
        if (bgp_debug_neighbor_events(peer))
8342
0
          zlog_debug(
8343
0
            "%pBP configured Graceful-Restart, skipping unconfig notification",
8344
0
            peer);
8345
0
        continue;
8346
0
      }
8347
0
      if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
8348
0
        bgp_notify_send(peer, BGP_NOTIFY_CEASE,
8349
0
            BGP_NOTIFY_CEASE_PEER_UNCONFIG);
8350
0
    }
8351
0
  }
8352
8353
0
  if (bm->listen_sockets)
8354
0
    list_delete(&bm->listen_sockets);
8355
8356
0
  EVENT_OFF(bm->t_rmap_update);
8357
8358
0
  bgp_mac_finish();
8359
0
}
8360
8361
struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp,
8362
         const char *ip_str, bool use_json)
8363
0
{
8364
0
  int ret;
8365
0
  struct peer *peer;
8366
0
  union sockunion su;
8367
8368
  /* Get peer sockunion. */
8369
0
  ret = str2sockunion(ip_str, &su);
8370
0
  if (ret < 0) {
8371
0
    peer = peer_lookup_by_conf_if(bgp, ip_str);
8372
0
    if (!peer) {
8373
0
      peer = peer_lookup_by_hostname(bgp, ip_str);
8374
8375
0
      if (!peer) {
8376
0
        if (use_json) {
8377
0
          json_object *json_no = NULL;
8378
0
          json_no = json_object_new_object();
8379
0
          json_object_string_add(
8380
0
            json_no,
8381
0
            "malformedAddressOrName",
8382
0
            ip_str);
8383
0
          vty_json(vty, json_no);
8384
0
        } else
8385
0
          vty_out(vty,
8386
0
            "%% Malformed address or name: %s\n",
8387
0
            ip_str);
8388
0
        return NULL;
8389
0
      }
8390
0
    }
8391
0
    return peer;
8392
0
  }
8393
8394
  /* Peer structure lookup. */
8395
0
  peer = peer_lookup(bgp, &su);
8396
0
  if (!peer) {
8397
0
    if (use_json) {
8398
0
      json_object *json_no = NULL;
8399
0
      json_no = json_object_new_object();
8400
0
      json_object_string_add(json_no, "warning",
8401
0
                 "No such neighbor in this view/vrf");
8402
0
      vty_json(vty, json_no);
8403
0
    } else
8404
0
      vty_out(vty, "No such neighbor in this view/vrf\n");
8405
0
    return NULL;
8406
0
  }
8407
8408
0
  return peer;
8409
0
}
8410
8411
void bgp_gr_apply_running_config(void)
8412
0
{
8413
0
  struct peer *peer = NULL;
8414
0
  struct bgp *bgp = NULL;
8415
0
  struct listnode *node, *nnode;
8416
0
  bool gr_router_detected = false;
8417
8418
0
  if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
8419
0
    zlog_debug("[BGP_GR] %s called !", __func__);
8420
8421
0
  for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
8422
0
    for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
8423
0
      bgp_peer_gr_flags_update(peer);
8424
0
      if (CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART))
8425
0
        gr_router_detected = true;
8426
0
    }
8427
8428
0
    if (gr_router_detected
8429
0
        && bgp->present_zebra_gr_state == ZEBRA_GR_DISABLE) {
8430
0
      bgp_zebra_send_capabilities(bgp, true);
8431
0
    } else if (!gr_router_detected
8432
0
         && bgp->present_zebra_gr_state == ZEBRA_GR_ENABLE) {
8433
0
      bgp_zebra_send_capabilities(bgp, false);
8434
0
    }
8435
8436
0
    gr_router_detected = false;
8437
0
  }
8438
0
}
8439
8440
printfrr_ext_autoreg_p("BP", printfrr_bp);
8441
static ssize_t printfrr_bp(struct fbuf *buf, struct printfrr_eargs *ea,
8442
         const void *ptr)
8443
0
{
8444
0
  const struct peer *peer = ptr;
8445
8446
0
  if (!peer)
8447
0
    return bputs(buf, "(null)");
8448
8449
0
  return bprintfrr(buf, "%s(%s)", peer->host,
8450
0
       peer->hostname ? peer->hostname : "Unknown");
8451
0
}