Coverage Report

Created: 2026-05-11 06:50

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/frr/bgpd/bgp_network.c
Line
Count
Source
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/* BGP network related fucntions
3
 * Copyright (C) 1999 Kunihiro Ishiguro
4
 */
5
6
#include <zebra.h>
7
8
#include "frrevent.h"
9
#include "sockunion.h"
10
#include "sockopt.h"
11
#include "memory.h"
12
#include "log.h"
13
#include "if.h"
14
#include "prefix.h"
15
#include "command.h"
16
#include "privs.h"
17
#include "linklist.h"
18
#include "network.h"
19
#include "queue.h"
20
#include "hash.h"
21
#include "filter.h"
22
#include "ns.h"
23
#include "lib_errors.h"
24
#include "nexthop.h"
25
26
#include "bgpd/bgpd.h"
27
#include "bgpd/bgp_open.h"
28
#include "bgpd/bgp_fsm.h"
29
#include "bgpd/bgp_attr.h"
30
#include "bgpd/bgp_debug.h"
31
#include "bgpd/bgp_errors.h"
32
#include "bgpd/bgp_network.h"
33
#include "bgpd/bgp_zebra.h"
34
#include "bgpd/bgp_nht.h"
35
36
extern struct zebra_privs_t bgpd_privs;
37
38
static char *bgp_get_bound_name(struct peer *peer);
39
40
void bgp_dump_listener_info(struct vty *vty)
41
0
{
42
0
  struct listnode *node;
43
0
  struct bgp_listener *listener;
44
45
0
  vty_out(vty, "Name             fd Address\n");
46
0
  vty_out(vty, "---------------------------\n");
47
0
  for (ALL_LIST_ELEMENTS_RO(bm->listen_sockets, node, listener))
48
0
    vty_out(vty, "%-16s %d %pSU\n",
49
0
      listener->name ? listener->name : VRF_DEFAULT_NAME,
50
0
      listener->fd, &listener->su);
51
0
}
52
53
/*
54
 * Set MD5 key for the socket, for the given IPv4 peer address.
55
 * If the password is NULL or zero-length, the option will be disabled.
56
 */
57
static int bgp_md5_set_socket(int socket, union sockunion *su,
58
            uint16_t prefixlen, const char *password)
59
0
{
60
0
  int ret = -1;
61
0
  int en = ENOSYS;
62
0
#if HAVE_DECL_TCP_MD5SIG
63
0
  union sockunion su2;
64
0
#endif /* HAVE_TCP_MD5SIG */
65
66
0
  assert(socket >= 0);
67
68
0
#if HAVE_DECL_TCP_MD5SIG
69
  /* Ensure there is no extraneous port information. */
70
0
  memcpy(&su2, su, sizeof(union sockunion));
71
0
  if (su2.sa.sa_family == AF_INET)
72
0
    su2.sin.sin_port = 0;
73
0
  else
74
0
    su2.sin6.sin6_port = 0;
75
76
  /* For addresses, use the non-extended signature functionality */
77
0
  if ((su2.sa.sa_family == AF_INET && prefixlen == IPV4_MAX_BITLEN)
78
0
      || (su2.sa.sa_family == AF_INET6 && prefixlen == IPV6_MAX_BITLEN))
79
0
    ret = sockopt_tcp_signature(socket, &su2, password);
80
0
  else
81
0
    ret = sockopt_tcp_signature_ext(socket, &su2, prefixlen,
82
0
            password);
83
0
  en = errno;
84
0
#endif /* HAVE_TCP_MD5SIG */
85
86
0
  if (ret < 0) {
87
0
    switch (ret) {
88
0
    case -2:
89
0
      flog_warn(
90
0
        EC_BGP_NO_TCP_MD5,
91
0
        "Unable to set TCP MD5 option on socket for peer %pSU (sock=%d): This platform does not support MD5 auth for prefixes",
92
0
        su, socket);
93
0
      break;
94
0
    default:
95
0
      flog_warn(
96
0
        EC_BGP_NO_TCP_MD5,
97
0
        "Unable to set TCP MD5 option on socket for peer %pSU (sock=%d): %s",
98
0
        su, socket, safe_strerror(en));
99
0
    }
100
0
  }
101
102
0
  return ret;
103
0
}
104
105
/* Helper for bgp_connect */
106
static int bgp_md5_set_connect(int socket, union sockunion *su,
107
             uint16_t prefixlen, const char *password)
108
0
{
109
0
  int ret = -1;
110
111
0
#if HAVE_DECL_TCP_MD5SIG
112
0
  frr_with_privs(&bgpd_privs) {
113
0
    ret = bgp_md5_set_socket(socket, su, prefixlen, password);
114
0
  }
115
0
#endif /* HAVE_TCP_MD5SIG */
116
117
0
  return ret;
118
0
}
119
120
static int bgp_md5_set_password(struct peer *peer, const char *password)
121
0
{
122
0
  struct listnode *node;
123
0
  int ret = 0;
124
0
  struct bgp_listener *listener;
125
126
  /*
127
   * Set or unset the password on the listen socket(s). Outbound
128
   * connections are taken care of in bgp_connect() below.
129
   */
130
0
  frr_with_privs(&bgpd_privs) {
131
0
    for (ALL_LIST_ELEMENTS_RO(bm->listen_sockets, node, listener))
132
0
      if (listener->su.sa.sa_family ==
133
0
          peer->su.sa.sa_family) {
134
0
        uint16_t prefixlen =
135
0
          peer->su.sa.sa_family == AF_INET
136
0
            ? IPV4_MAX_BITLEN
137
0
            : IPV6_MAX_BITLEN;
138
139
        /*
140
         * if we have stored a BGP vrf instance in the
141
         * listener it must match the bgp instance in
142
         * the peer otherwise the peer bgp instance
143
         * must be the default vrf or a view instance
144
         */
145
0
        if (!listener->bgp) {
146
0
          if (peer->bgp->vrf_id != VRF_DEFAULT)
147
0
            continue;
148
0
        } else if (listener->bgp != peer->bgp)
149
0
          continue;
150
151
0
        ret = bgp_md5_set_socket(listener->fd,
152
0
               &peer->su, prefixlen,
153
0
               password);
154
0
        break;
155
0
      }
156
0
  }
157
0
  return ret;
158
0
}
159
160
int bgp_md5_set_prefix(struct bgp *bgp, struct prefix *p, const char *password)
161
0
{
162
0
  int ret = 0;
163
0
  union sockunion su;
164
0
  struct listnode *node;
165
0
  struct bgp_listener *listener;
166
167
  /* Set or unset the password on the listen socket(s). */
168
0
  frr_with_privs(&bgpd_privs) {
169
0
    for (ALL_LIST_ELEMENTS_RO(bm->listen_sockets, node, listener))
170
0
      if (listener->su.sa.sa_family == p->family
171
0
          && ((bgp->vrf_id == VRF_DEFAULT)
172
0
        || (listener->bgp == bgp))) {
173
0
        prefix2sockunion(p, &su);
174
0
        ret = bgp_md5_set_socket(listener->fd, &su,
175
0
               p->prefixlen,
176
0
               password);
177
0
        break;
178
0
      }
179
0
  }
180
181
0
  return ret;
182
0
}
183
184
int bgp_md5_unset_prefix(struct bgp *bgp, struct prefix *p)
185
0
{
186
0
  return bgp_md5_set_prefix(bgp, p, NULL);
187
0
}
188
189
int bgp_md5_set(struct peer *peer)
190
0
{
191
  /* Set the password from listen socket. */
192
0
  return bgp_md5_set_password(peer, peer->password);
193
0
}
194
195
static void bgp_update_setsockopt_tcp_keepalive(struct bgp *bgp, int fd)
196
0
{
197
0
  if (!bgp)
198
0
    return;
199
0
  if (bgp->tcp_keepalive_idle != 0) {
200
0
    int ret;
201
202
0
    ret = setsockopt_tcp_keepalive(fd, bgp->tcp_keepalive_idle,
203
0
                 bgp->tcp_keepalive_intvl,
204
0
                 bgp->tcp_keepalive_probes);
205
0
    if (ret < 0)
206
0
      zlog_err(
207
0
        "Can't set TCP keepalive on socket %d, idle %u intvl %u probes %u",
208
0
        fd, bgp->tcp_keepalive_idle,
209
0
        bgp->tcp_keepalive_intvl,
210
0
        bgp->tcp_keepalive_probes);
211
0
  }
212
0
}
213
214
int bgp_md5_unset(struct peer *peer)
215
0
{
216
  /* Unset the password from listen socket. */
217
0
  return bgp_md5_set_password(peer, NULL);
218
0
}
219
220
int bgp_set_socket_ttl(struct peer *peer, int bgp_sock)
221
0
{
222
0
  int ret = 0;
223
224
0
  if (!peer->gtsm_hops) {
225
0
    ret = sockopt_ttl(peer->su.sa.sa_family, bgp_sock, peer->ttl);
226
0
    if (ret) {
227
0
      flog_err(
228
0
        EC_LIB_SOCKET,
229
0
        "%s: Can't set TxTTL on peer (rtrid %pI4) socket, err = %d",
230
0
        __func__, &peer->remote_id, errno);
231
0
      return ret;
232
0
    }
233
0
  } else {
234
    /* On Linux, setting minttl without setting ttl seems to mess
235
       with the
236
       outgoing ttl. Therefore setting both.
237
    */
238
0
    ret = sockopt_ttl(peer->su.sa.sa_family, bgp_sock, MAXTTL);
239
0
    if (ret) {
240
0
      flog_err(
241
0
        EC_LIB_SOCKET,
242
0
        "%s: Can't set TxTTL on peer (rtrid %pI4) socket, err = %d",
243
0
        __func__, &peer->remote_id, errno);
244
0
      return ret;
245
0
    }
246
0
    ret = sockopt_minttl(peer->su.sa.sa_family, bgp_sock,
247
0
             MAXTTL + 1 - peer->gtsm_hops);
248
0
    if (ret) {
249
0
      flog_err(
250
0
        EC_LIB_SOCKET,
251
0
        "%s: Can't set MinTTL on peer (rtrid %pI4) socket, err = %d",
252
0
        __func__, &peer->remote_id, errno);
253
0
      return ret;
254
0
    }
255
0
  }
256
257
0
  return ret;
258
0
}
259
260
/*
261
 * Obtain the BGP instance that the incoming connection should be processed
262
 * against. This is important because more than one VRF could be using the
263
 * same IP address space. The instance is got by obtaining the device to
264
 * which the incoming connection is bound to. This could either be a VRF
265
 * or it could be an interface, which in turn determines the VRF.
266
 */
267
static int bgp_get_instance_for_inc_conn(int sock, struct bgp **bgp_inst)
268
0
{
269
0
#ifndef SO_BINDTODEVICE
270
0
  /* only Linux has SO_BINDTODEVICE, but we're in Linux-specific code here
271
0
   * anyway since the assumption is that the interface name returned by
272
0
   * getsockopt() is useful in identifying the VRF, particularly with
273
0
   * Linux's
274
0
   * VRF l3master device.  The whole mechanism is specific to Linux, so...
275
0
   * when other platforms add VRF support, this will need handling here as
276
0
   * well.  (or, some restructuring) */
277
0
  *bgp_inst = bgp_get_default();
278
0
  return !*bgp_inst;
279
0
280
0
#else
281
0
  char name[VRF_NAMSIZ + 1];
282
0
  socklen_t name_len = VRF_NAMSIZ;
283
0
  struct bgp *bgp;
284
0
  int rc;
285
0
  struct listnode *node, *nnode;
286
0
287
0
  *bgp_inst = NULL;
288
0
  name[0] = '\0';
289
0
  rc = getsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, name, &name_len);
290
0
  if (rc != 0) {
291
0
#if defined(HAVE_CUMULUS)
292
0
    flog_err(EC_LIB_SOCKET,
293
0
       "[Error] BGP SO_BINDTODEVICE get failed (%s), sock %d",
294
0
       safe_strerror(errno), sock);
295
0
    return -1;
296
0
#endif
297
0
  }
298
0
299
0
  if (!strlen(name)) {
300
0
    *bgp_inst = bgp_get_default();
301
0
    return 0; /* default instance. */
302
0
  }
303
0
304
0
  /* First try match to instance; if that fails, check for interfaces. */
305
0
  bgp = bgp_lookup_by_name(name);
306
0
  if (bgp) {
307
0
    if (!bgp->vrf_id) // unexpected
308
0
      return -1;
309
0
    *bgp_inst = bgp;
310
0
    return 0;
311
0
  }
312
0
313
0
  /* TODO - This will be optimized once interfaces move into the NS */
314
0
  for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
315
0
    struct interface *ifp;
316
0
317
0
    if (bgp->inst_type == BGP_INSTANCE_TYPE_VIEW)
318
0
      continue;
319
0
320
0
    ifp = if_lookup_by_name(name, bgp->vrf_id);
321
0
    if (ifp) {
322
0
      *bgp_inst = bgp;
323
0
      return 0;
324
0
    }
325
0
  }
326
0
327
0
  /* We didn't match to either an instance or an interface. */
328
0
  return -1;
329
0
#endif
330
0
}
331
332
static void bgp_socket_set_buffer_size(const int fd)
333
0
{
334
0
  if (getsockopt_so_sendbuf(fd) < (int)bm->socket_buffer)
335
0
    setsockopt_so_sendbuf(fd, bm->socket_buffer);
336
0
  if (getsockopt_so_recvbuf(fd) < (int)bm->socket_buffer)
337
0
    setsockopt_so_recvbuf(fd, bm->socket_buffer);
338
0
}
339
340
/* Accept bgp connection. */
341
static void bgp_accept(struct event *thread)
342
0
{
343
0
  int bgp_sock;
344
0
  int accept_sock;
345
0
  union sockunion su;
346
0
  struct bgp_listener *listener = EVENT_ARG(thread);
347
0
  struct peer *peer;
348
0
  struct peer *peer1;
349
0
  char buf[SU_ADDRSTRLEN];
350
0
  struct bgp *bgp = NULL;
351
0
352
0
  sockunion_init(&su);
353
0
354
0
  bgp = bgp_lookup_by_name(listener->name);
355
0
356
0
  /* Register accept thread. */
357
0
  accept_sock = EVENT_FD(thread);
358
0
  if (accept_sock < 0) {
359
0
    flog_err_sys(EC_LIB_SOCKET,
360
0
           "[Error] BGP accept socket fd is negative: %d",
361
0
           accept_sock);
362
0
    return;
363
0
  }
364
0
365
0
  event_add_read(bm->master, bgp_accept, listener, accept_sock,
366
0
           &listener->thread);
367
0
368
0
  /* Accept client connection. */
369
0
  bgp_sock = sockunion_accept(accept_sock, &su);
370
0
  int save_errno = errno;
371
0
  if (bgp_sock < 0) {
372
0
    if (save_errno == EINVAL) {
373
0
      struct vrf *vrf =
374
0
        bgp ? vrf_lookup_by_id(bgp->vrf_id) : NULL;
375
0
376
0
      /*
377
0
       * It appears that sometimes, when VRFs are deleted on
378
0
       * the system, it takes a little while for us to get
379
0
       * notified about that. In the meantime we endlessly
380
0
       * loop on accept(), because the socket, having been
381
0
       * bound to a now-deleted VRF device, is in some weird
382
0
       * state which causes accept() to fail.
383
0
       *
384
0
       * To avoid this, if we see accept() fail with EINVAL,
385
0
       * we cancel ourselves and trust that when the VRF
386
0
       * deletion notification comes in the event handler for
387
0
       * that will take care of cleaning us up.
388
0
       */
389
0
      flog_err_sys(
390
0
        EC_LIB_SOCKET,
391
0
        "[Error] accept() failed with error \"%s\" on BGP listener socket %d for BGP instance in VRF \"%s\"; refreshing socket",
392
0
        safe_strerror(save_errno), accept_sock,
393
0
        VRF_LOGNAME(vrf));
394
0
      EVENT_OFF(listener->thread);
395
0
    } else {
396
0
      flog_err_sys(
397
0
        EC_LIB_SOCKET,
398
0
        "[Error] BGP socket accept failed (%s); retrying",
399
0
        safe_strerror(save_errno));
400
0
    }
401
0
    return;
402
0
  }
403
0
  set_nonblocking(bgp_sock);
404
0
405
0
  /* Obtain BGP instance this connection is meant for.
406
0
   * - if it is a VRF netns sock, then BGP is in listener structure
407
0
   * - otherwise, the bgp instance need to be demultiplexed
408
0
   */
409
0
  if (listener->bgp)
410
0
    bgp = listener->bgp;
411
0
  else if (bgp_get_instance_for_inc_conn(bgp_sock, &bgp)) {
412
0
    if (bgp_debug_neighbor_events(NULL))
413
0
      zlog_debug(
414
0
        "[Event] Could not get instance for incoming conn from %s",
415
0
        inet_sutop(&su, buf));
416
0
    close(bgp_sock);
417
0
    return;
418
0
  }
419
0
420
0
  bgp_socket_set_buffer_size(bgp_sock);
421
0
422
0
  /* Set TCP keepalive when TCP keepalive is enabled */
423
0
  bgp_update_setsockopt_tcp_keepalive(bgp, bgp_sock);
424
0
425
0
  /* Check remote IP address */
426
0
  peer1 = peer_lookup(bgp, &su);
427
0
428
0
  if (!peer1) {
429
0
    peer1 = peer_lookup_dynamic_neighbor(bgp, &su);
430
0
    if (peer1) {
431
0
      /* Dynamic neighbor has been created, let it proceed */
432
0
      peer1->fd = bgp_sock;
433
0
434
0
      /* Set the user configured MSS to TCP socket */
435
0
      if (CHECK_FLAG(peer1->flags, PEER_FLAG_TCP_MSS))
436
0
        sockopt_tcp_mss_set(bgp_sock, peer1->tcp_mss);
437
0
438
0
      bgp_fsm_change_status(peer1, Active);
439
0
      EVENT_OFF(
440
0
        peer1->t_start); /* created in peer_create() */
441
0
442
0
      if (peer_active(peer1)) {
443
0
        if (CHECK_FLAG(peer1->flags,
444
0
                 PEER_FLAG_TIMER_DELAYOPEN))
445
0
          BGP_EVENT_ADD(
446
0
            peer1,
447
0
            TCP_connection_open_w_delay);
448
0
        else
449
0
          BGP_EVENT_ADD(peer1,
450
0
                  TCP_connection_open);
451
0
      }
452
0
453
0
      return;
454
0
    }
455
0
  }
456
0
457
0
  if (!peer1) {
458
0
    if (bgp_debug_neighbor_events(NULL)) {
459
0
      zlog_debug(
460
0
        "[Event] %s connection rejected(%s:%u:%s) - not configured and not valid for dynamic",
461
0
        inet_sutop(&su, buf), bgp->name_pretty, bgp->as,
462
0
        VRF_LOGNAME(vrf_lookup_by_id(bgp->vrf_id)));
463
0
    }
464
0
    close(bgp_sock);
465
0
    return;
466
0
  }
467
0
468
0
  if (CHECK_FLAG(peer1->flags, PEER_FLAG_SHUTDOWN)
469
0
      || CHECK_FLAG(peer1->bgp->flags, BGP_FLAG_SHUTDOWN)) {
470
0
    if (bgp_debug_neighbor_events(peer1))
471
0
      zlog_debug(
472
0
        "[Event] connection from %s rejected(%s:%u:%s) due to admin shutdown",
473
0
        inet_sutop(&su, buf), bgp->name_pretty, bgp->as,
474
0
        VRF_LOGNAME(vrf_lookup_by_id(bgp->vrf_id)));
475
0
    close(bgp_sock);
476
0
    return;
477
0
  }
478
0
479
0
  /*
480
0
   * Do not accept incoming connections in Clearing state. This can result
481
0
   * in incorect state transitions - e.g., the connection goes back to
482
0
   * Established and then the Clearing_Completed event is generated. Also,
483
0
   * block incoming connection in Deleted state.
484
0
   */
485
0
  if (peer1->status == Clearing || peer1->status == Deleted) {
486
0
    if (bgp_debug_neighbor_events(peer1))
487
0
      zlog_debug(
488
0
        "[Event] Closing incoming conn for %s (%p) state %d",
489
0
        peer1->host, peer1, peer1->status);
490
0
    close(bgp_sock);
491
0
    return;
492
0
  }
493
0
494
0
  /* Check that at least one AF is activated for the peer. */
495
0
  if (!peer_active(peer1)) {
496
0
    if (bgp_debug_neighbor_events(peer1))
497
0
      zlog_debug(
498
0
        "%s - incoming conn rejected - no AF activated for peer",
499
0
        peer1->host);
500
0
    close(bgp_sock);
501
0
    return;
502
0
  }
503
0
504
0
  /* Do not try to reconnect if the peer reached maximum
505
0
   * prefixes, restart timer is still running or the peer
506
0
   * is shutdown.
507
0
   */
508
0
  if (BGP_PEER_START_SUPPRESSED(peer1)) {
509
0
    if (bgp_debug_neighbor_events(peer1)) {
510
0
      if (peer1->shut_during_cfg)
511
0
        zlog_debug(
512
0
          "[Event] Incoming BGP connection rejected from %s due to configuration being currently read in",
513
0
          peer1->host);
514
0
      else
515
0
        zlog_debug(
516
0
          "[Event] Incoming BGP connection rejected from %s due to maximum-prefix or shutdown",
517
0
          peer1->host);
518
0
    }
519
0
    close(bgp_sock);
520
0
    return;
521
0
  }
522
0
523
0
  if (bgp_debug_neighbor_events(peer1))
524
0
    zlog_debug(
525
0
      "[Event] connection from %s fd %d, active peer status %d fd %d",
526
0
      inet_sutop(&su, buf), bgp_sock, peer1->status,
527
0
      peer1->fd);
528
0
529
0
  if (peer1->doppelganger) {
530
0
    /* We have an existing connection. Kill the existing one and run
531
0
       with this one.
532
0
    */
533
0
    if (bgp_debug_neighbor_events(peer1))
534
0
      zlog_debug(
535
0
        "[Event] New active connection from peer %s, Killing previous active connection",
536
0
        peer1->host);
537
0
    peer_delete(peer1->doppelganger);
538
0
  }
539
0
540
0
  if (bgp_set_socket_ttl(peer1, bgp_sock) < 0)
541
0
    if (bgp_debug_neighbor_events(peer1))
542
0
      zlog_debug(
543
0
        "[Event] Unable to set min/max TTL on peer %s, Continuing",
544
0
        peer1->host);
545
0
546
0
  peer = peer_create(&su, peer1->conf_if, peer1->bgp, peer1->local_as,
547
0
         peer1->as, peer1->as_type, NULL, false, NULL);
548
0
549
0
  peer_xfer_config(peer, peer1);
550
0
  bgp_peer_gr_flags_update(peer);
551
0
552
0
  BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(peer->bgp,
553
0
                peer->bgp->peer);
554
0
555
0
  if (bgp_peer_gr_mode_get(peer) == PEER_DISABLE) {
556
0
557
0
    UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE);
558
0
559
0
    if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)) {
560
0
      peer_nsf_stop(peer);
561
0
    }
562
0
  }
563
0
564
0
  peer->doppelganger = peer1;
565
0
  peer1->doppelganger = peer;
566
0
  peer->fd = bgp_sock;
567
0
  frr_with_privs(&bgpd_privs) {
568
0
    vrf_bind(peer->bgp->vrf_id, bgp_sock, bgp_get_bound_name(peer));
569
0
  }
570
0
  bgp_peer_reg_with_nht(peer);
571
0
  bgp_fsm_change_status(peer, Active);
572
0
  EVENT_OFF(peer->t_start); /* created in peer_create() */
573
0
574
0
  SET_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER);
575
0
  /* Make dummy peer until read Open packet. */
576
0
  if (peer_established(peer1)
577
0
      && CHECK_FLAG(peer1->sflags, PEER_STATUS_NSF_MODE)) {
578
0
    /* If we have an existing established connection with graceful
579
0
     * restart
580
0
     * capability announced with one or more address families, then
581
0
     * drop
582
0
     * existing established connection and move state to connect.
583
0
     */
584
0
    peer1->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
585
0
586
0
    if (CHECK_FLAG(peer1->flags, PEER_FLAG_GRACEFUL_RESTART)
587
0
        || CHECK_FLAG(peer1->flags,
588
0
          PEER_FLAG_GRACEFUL_RESTART_HELPER))
589
0
      SET_FLAG(peer1->sflags, PEER_STATUS_NSF_WAIT);
590
0
591
0
    bgp_event_update(peer1, TCP_connection_closed);
592
0
  }
593
0
594
0
  if (peer_active(peer)) {
595
0
    if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER_DELAYOPEN))
596
0
      BGP_EVENT_ADD(peer, TCP_connection_open_w_delay);
597
0
    else
598
0
      BGP_EVENT_ADD(peer, TCP_connection_open);
599
0
  }
600
0
601
0
  /*
602
0
   * If we are doing nht for a peer that is v6 LL based
603
0
   * massage the event system to make things happy
604
0
   */
605
0
  bgp_nht_interface_events(peer);
606
0
}
607
608
/* BGP socket bind. */
609
static char *bgp_get_bound_name(struct peer *peer)
610
0
{
611
0
  if (!peer)
612
0
    return NULL;
613
614
0
  if ((peer->bgp->vrf_id == VRF_DEFAULT) && !peer->ifname
615
0
      && !peer->conf_if)
616
0
    return NULL;
617
618
0
  if (peer->su.sa.sa_family != AF_INET
619
0
      && peer->su.sa.sa_family != AF_INET6)
620
0
    return NULL; // unexpected
621
622
  /* For IPv6 peering, interface (unnumbered or link-local with interface)
623
   * takes precedence over VRF. For IPv4 peering, explicit interface or
624
   * VRF are the situations to bind.
625
   */
626
0
  if (peer->su.sa.sa_family == AF_INET6 && peer->conf_if)
627
0
    return peer->conf_if;
628
629
0
  if (peer->ifname)
630
0
    return peer->ifname;
631
632
0
  if (peer->bgp->inst_type == BGP_INSTANCE_TYPE_VIEW)
633
0
    return NULL;
634
635
0
  return peer->bgp->name;
636
0
}
637
638
int bgp_update_address(struct interface *ifp, const union sockunion *dst,
639
            union sockunion *addr)
640
0
{
641
0
  struct prefix *p, *sel, d;
642
0
  struct connected *connected;
643
0
  struct listnode *node;
644
0
  int common;
645
646
0
  if (!sockunion2hostprefix(dst, &d))
647
0
    return 1;
648
649
0
  sel = NULL;
650
0
  common = -1;
651
652
0
  for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected)) {
653
0
    p = connected->address;
654
0
    if (p->family != d.family)
655
0
      continue;
656
0
    if (prefix_common_bits(p, &d) > common) {
657
0
      sel = p;
658
0
      common = prefix_common_bits(sel, &d);
659
0
    }
660
0
  }
661
662
0
  if (!sel)
663
0
    return 1;
664
665
0
  prefix2sockunion(sel, addr);
666
0
  return 0;
667
0
}
668
669
/* Update source selection.  */
670
static int bgp_update_source(struct peer *peer)
671
0
{
672
0
  struct interface *ifp;
673
0
  union sockunion addr;
674
0
  int ret = 0;
675
676
0
  sockunion_init(&addr);
677
678
  /* Source is specified with interface name.  */
679
0
  if (peer->update_if) {
680
0
    ifp = if_lookup_by_name(peer->update_if, peer->bgp->vrf_id);
681
0
    if (!ifp)
682
0
      return -1;
683
684
0
    if (bgp_update_address(ifp, &peer->su, &addr))
685
0
      return -1;
686
687
0
    ret = sockunion_bind(peer->fd, &addr, 0, &addr);
688
0
  }
689
690
  /* Source is specified with IP address.  */
691
0
  if (peer->update_source)
692
0
    ret = sockunion_bind(peer->fd, peer->update_source, 0,
693
0
             peer->update_source);
694
695
0
  return ret;
696
0
}
697
698
/* BGP try to connect to the peer.  */
699
int bgp_connect(struct peer *peer)
700
0
{
701
0
  assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_WRITES_ON));
702
0
  assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_READS_ON));
703
0
  ifindex_t ifindex = 0;
704
705
0
  if (peer->conf_if && BGP_PEER_SU_UNSPEC(peer)) {
706
0
    if (bgp_debug_neighbor_events(peer))
707
0
      zlog_debug("Peer address not learnt: Returning from connect");
708
0
    return 0;
709
0
  }
710
0
  frr_with_privs(&bgpd_privs) {
711
  /* Make socket for the peer. */
712
0
    peer->fd = vrf_sockunion_socket(&peer->su, peer->bgp->vrf_id,
713
0
            bgp_get_bound_name(peer));
714
0
  }
715
0
  if (peer->fd < 0) {
716
0
    peer->last_reset = PEER_DOWN_SOCKET_ERROR;
717
0
    if (bgp_debug_neighbor_events(peer))
718
0
      zlog_debug("%s: Failure to create socket for connection to %s, error received: %s(%d)",
719
0
           __func__, peer->host, safe_strerror(errno),
720
0
           errno);
721
0
    return -1;
722
0
  }
723
724
0
  set_nonblocking(peer->fd);
725
726
  /* Set the user configured MSS to TCP socket */
727
0
  if (CHECK_FLAG(peer->flags, PEER_FLAG_TCP_MSS))
728
0
    sockopt_tcp_mss_set(peer->fd, peer->tcp_mss);
729
730
0
  bgp_socket_set_buffer_size(peer->fd);
731
732
  /* Set TCP keepalive when TCP keepalive is enabled */
733
0
  bgp_update_setsockopt_tcp_keepalive(peer->bgp, peer->fd);
734
735
0
  if (bgp_set_socket_ttl(peer, peer->fd) < 0) {
736
0
    peer->last_reset = PEER_DOWN_SOCKET_ERROR;
737
0
    if (bgp_debug_neighbor_events(peer))
738
0
      zlog_debug("%s: Failure to set socket ttl for connection to %s, error received: %s(%d)",
739
0
           __func__, peer->host, safe_strerror(errno),
740
0
           errno);
741
742
0
    return -1;
743
0
  }
744
745
0
  sockopt_reuseaddr(peer->fd);
746
0
  sockopt_reuseport(peer->fd);
747
748
0
#ifdef IPTOS_PREC_INTERNETCONTROL
749
0
  frr_with_privs(&bgpd_privs) {
750
0
    if (sockunion_family(&peer->su) == AF_INET)
751
0
      setsockopt_ipv4_tos(peer->fd, bm->tcp_dscp);
752
0
    else if (sockunion_family(&peer->su) == AF_INET6)
753
0
      setsockopt_ipv6_tclass(peer->fd, bm->tcp_dscp);
754
0
  }
755
0
#endif
756
757
0
  if (peer->password) {
758
0
    uint16_t prefixlen = peer->su.sa.sa_family == AF_INET
759
0
               ? IPV4_MAX_BITLEN
760
0
               : IPV6_MAX_BITLEN;
761
762
0
    if (!BGP_PEER_SU_UNSPEC(peer))
763
0
      bgp_md5_set(peer);
764
765
0
    bgp_md5_set_connect(peer->fd, &peer->su, prefixlen,
766
0
            peer->password);
767
0
  }
768
769
  /* Update source bind. */
770
0
  if (bgp_update_source(peer) < 0) {
771
0
    peer->last_reset = PEER_DOWN_SOCKET_ERROR;
772
0
    return connect_error;
773
0
  }
774
775
0
  if (peer->conf_if || peer->ifname)
776
0
    ifindex = ifname2ifindex(peer->conf_if ? peer->conf_if
777
0
                   : peer->ifname,
778
0
           peer->bgp->vrf_id);
779
780
0
  if (bgp_debug_neighbor_events(peer))
781
0
    zlog_debug("%s [Event] Connect start to %s fd %d", peer->host,
782
0
         peer->host, peer->fd);
783
784
  /* Connect to the remote peer. */
785
0
  return sockunion_connect(peer->fd, &peer->su, htons(peer->port),
786
0
         ifindex);
787
0
}
788
789
/* After TCP connection is established.  Get local address and port. */
790
int bgp_getsockname(struct peer *peer)
791
0
{
792
0
  if (peer->su_local) {
793
0
    sockunion_free(peer->su_local);
794
0
    peer->su_local = NULL;
795
0
  }
796
797
0
  if (peer->su_remote) {
798
0
    sockunion_free(peer->su_remote);
799
0
    peer->su_remote = NULL;
800
0
  }
801
802
0
  peer->su_local = sockunion_getsockname(peer->fd);
803
0
  if (!peer->su_local)
804
0
    return -1;
805
0
  peer->su_remote = sockunion_getpeername(peer->fd);
806
0
  if (!peer->su_remote)
807
0
    return -1;
808
809
0
  if (!bgp_zebra_nexthop_set(peer->su_local, peer->su_remote,
810
0
           &peer->nexthop, peer)) {
811
0
    flog_err(
812
0
      EC_BGP_NH_UPD,
813
0
      "%s: nexthop_set failed, resetting connection - intf %s",
814
0
      peer->host,
815
0
      peer->nexthop.ifp ? peer->nexthop.ifp->name
816
0
            : "(Unknown)");
817
0
    return -1;
818
0
  }
819
0
  return 0;
820
0
}
821
822
823
static int bgp_listener(int sock, struct sockaddr *sa, socklen_t salen,
824
      struct bgp *bgp)
825
0
{
826
0
  struct bgp_listener *listener;
827
0
  int ret, en;
828
829
0
  sockopt_reuseaddr(sock);
830
0
  sockopt_reuseport(sock);
831
832
0
  frr_with_privs(&bgpd_privs) {
833
834
0
#ifdef IPTOS_PREC_INTERNETCONTROL
835
0
    if (sa->sa_family == AF_INET)
836
0
      setsockopt_ipv4_tos(sock, bm->tcp_dscp);
837
0
    else if (sa->sa_family == AF_INET6)
838
0
      setsockopt_ipv6_tclass(sock, bm->tcp_dscp);
839
0
#endif
840
841
0
    sockopt_v6only(sa->sa_family, sock);
842
843
0
    ret = bind(sock, sa, salen);
844
0
    en = errno;
845
0
  }
846
847
0
  if (ret < 0) {
848
0
    flog_err_sys(EC_LIB_SOCKET, "bind: %s", safe_strerror(en));
849
0
    return ret;
850
0
  }
851
852
0
  ret = listen(sock, SOMAXCONN);
853
0
  if (ret < 0) {
854
0
    flog_err_sys(EC_LIB_SOCKET, "listen: %s", safe_strerror(errno));
855
0
    return ret;
856
0
  }
857
858
0
  listener = XCALLOC(MTYPE_BGP_LISTENER, sizeof(*listener));
859
0
  listener->fd = sock;
860
0
  listener->name = XSTRDUP(MTYPE_BGP_LISTENER, bgp->name);
861
862
  /* this socket is in a vrf record bgp back pointer */
863
0
  if (bgp->vrf_id != VRF_DEFAULT)
864
0
    listener->bgp = bgp;
865
866
0
  memcpy(&listener->su, sa, salen);
867
0
  event_add_read(bm->master, bgp_accept, listener, sock,
868
0
           &listener->thread);
869
0
  listnode_add(bm->listen_sockets, listener);
870
871
0
  return 0;
872
0
}
873
874
/* IPv6 supported version of BGP server socket setup.  */
875
int bgp_socket(struct bgp *bgp, unsigned short port, const char *address)
876
0
{
877
0
  struct addrinfo *ainfo;
878
0
  struct addrinfo *ainfo_save;
879
0
  static const struct addrinfo req = {
880
0
    .ai_family = AF_UNSPEC,
881
0
    .ai_flags = AI_PASSIVE,
882
0
    .ai_socktype = SOCK_STREAM,
883
0
  };
884
0
  int ret, count;
885
0
  char port_str[BUFSIZ];
886
887
0
  snprintf(port_str, sizeof(port_str), "%d", port);
888
0
  port_str[sizeof(port_str) - 1] = '\0';
889
890
0
  frr_with_privs(&bgpd_privs) {
891
0
    ret = vrf_getaddrinfo(address, port_str, &req, &ainfo_save,
892
0
              bgp->vrf_id);
893
0
  }
894
0
  if (ret != 0) {
895
0
    flog_err_sys(EC_LIB_SOCKET, "getaddrinfo: %s",
896
0
           gai_strerror(ret));
897
0
    return -1;
898
0
  }
899
0
  if (bgp_option_check(BGP_OPT_NO_ZEBRA) &&
900
0
      bgp->vrf_id != VRF_DEFAULT) {
901
0
    freeaddrinfo(ainfo_save);
902
0
    return -1;
903
0
  }
904
0
  count = 0;
905
0
  for (ainfo = ainfo_save; ainfo; ainfo = ainfo->ai_next) {
906
0
    int sock;
907
908
0
    if (ainfo->ai_family != AF_INET && ainfo->ai_family != AF_INET6)
909
0
      continue;
910
911
0
    frr_with_privs(&bgpd_privs) {
912
0
      sock = vrf_socket(ainfo->ai_family,
913
0
            ainfo->ai_socktype,
914
0
            ainfo->ai_protocol,
915
0
            bgp->vrf_id,
916
0
            (bgp->inst_type
917
0
             == BGP_INSTANCE_TYPE_VRF
918
0
             ? bgp->name : NULL));
919
0
    }
920
0
    if (sock < 0) {
921
0
      flog_err_sys(EC_LIB_SOCKET, "socket: %s",
922
0
             safe_strerror(errno));
923
0
      continue;
924
0
    }
925
926
    /* if we intend to implement ttl-security, this socket needs
927
     * ttl=255 */
928
0
    sockopt_ttl(ainfo->ai_family, sock, MAXTTL);
929
930
0
    ret = bgp_listener(sock, ainfo->ai_addr, ainfo->ai_addrlen,
931
0
           bgp);
932
0
    if (ret == 0)
933
0
      ++count;
934
0
    else
935
0
      close(sock);
936
0
  }
937
0
  freeaddrinfo(ainfo_save);
938
0
  if (count == 0 && bgp->inst_type != BGP_INSTANCE_TYPE_VRF) {
939
0
    flog_err(
940
0
      EC_LIB_SOCKET,
941
0
      "%s: no usable addresses please check other programs usage of specified port %d",
942
0
      __func__, port);
943
0
    flog_err_sys(EC_LIB_SOCKET, "%s: Program cannot continue",
944
0
           __func__);
945
0
    exit(-1);
946
0
  }
947
948
0
  return 0;
949
0
}
950
951
/* this function closes vrf socket
952
 * this should be called only for vrf socket with netns backend
953
 */
954
void bgp_close_vrf_socket(struct bgp *bgp)
955
0
{
956
0
  struct listnode *node, *next;
957
0
  struct bgp_listener *listener;
958
959
0
  if (!bgp)
960
0
    return;
961
962
0
  if (bm->listen_sockets == NULL)
963
0
    return;
964
965
0
  for (ALL_LIST_ELEMENTS(bm->listen_sockets, node, next, listener)) {
966
0
    if (listener->bgp == bgp) {
967
0
      EVENT_OFF(listener->thread);
968
0
      close(listener->fd);
969
0
      listnode_delete(bm->listen_sockets, listener);
970
0
      XFREE(MTYPE_BGP_LISTENER, listener->name);
971
0
      XFREE(MTYPE_BGP_LISTENER, listener);
972
0
    }
973
0
  }
974
0
}
975
976
/* this function closes main socket
977
 */
978
void bgp_close(void)
979
0
{
980
0
  struct listnode *node, *next;
981
0
  struct bgp_listener *listener;
982
983
0
  if (bm->listen_sockets == NULL)
984
0
    return;
985
986
0
  for (ALL_LIST_ELEMENTS(bm->listen_sockets, node, next, listener)) {
987
0
    if (listener->bgp)
988
0
      continue;
989
0
    EVENT_OFF(listener->thread);
990
0
    close(listener->fd);
991
0
    listnode_delete(bm->listen_sockets, listener);
992
0
    XFREE(MTYPE_BGP_LISTENER, listener->name);
993
    XFREE(MTYPE_BGP_LISTENER, listener);
994
0
  }
995
0
}