]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_network.c
Merge pull request #2856 from opensourcerouting/bfd-work
[mirror_frr.git] / bgpd / bgp_network.c
1 /* BGP network related fucntions
2 * Copyright (C) 1999 Kunihiro Ishiguro
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include <zebra.h>
22
23 #include "thread.h"
24 #include "sockunion.h"
25 #include "sockopt.h"
26 #include "memory.h"
27 #include "log.h"
28 #include "if.h"
29 #include "prefix.h"
30 #include "command.h"
31 #include "privs.h"
32 #include "linklist.h"
33 #include "network.h"
34 #include "queue.h"
35 #include "hash.h"
36 #include "filter.h"
37 #include "ns.h"
38 #include "lib_errors.h"
39
40 #include "bgpd/bgpd.h"
41 #include "bgpd/bgp_open.h"
42 #include "bgpd/bgp_fsm.h"
43 #include "bgpd/bgp_attr.h"
44 #include "bgpd/bgp_debug.h"
45 #include "bgpd/bgp_errors.h"
46 #include "bgpd/bgp_network.h"
47
48 extern struct zebra_privs_t bgpd_privs;
49
50 static char *bgp_get_bound_name(struct peer *peer);
51
52 /* BGP listening socket. */
53 struct bgp_listener {
54 int fd;
55 union sockunion su;
56 struct thread *thread;
57 struct bgp *bgp;
58 };
59
60 /*
61 * Set MD5 key for the socket, for the given IPv4 peer address.
62 * If the password is NULL or zero-length, the option will be disabled.
63 */
64 static int bgp_md5_set_socket(int socket, union sockunion *su,
65 const char *password)
66 {
67 int ret = -1;
68 int en = ENOSYS;
69 #if HAVE_DECL_TCP_MD5SIG
70 union sockunion su2;
71 #endif /* HAVE_TCP_MD5SIG */
72
73 assert(socket >= 0);
74
75 #if HAVE_DECL_TCP_MD5SIG
76 /* Ensure there is no extraneous port information. */
77 memcpy(&su2, su, sizeof(union sockunion));
78 if (su2.sa.sa_family == AF_INET)
79 su2.sin.sin_port = 0;
80 else
81 su2.sin6.sin6_port = 0;
82 ret = sockopt_tcp_signature(socket, &su2, password);
83 en = errno;
84 #endif /* HAVE_TCP_MD5SIG */
85
86 if (ret < 0)
87 zlog_warn("can't set TCP_MD5SIG option on socket %d: %s",
88 socket, safe_strerror(en));
89
90 return ret;
91 }
92
93 /* Helper for bgp_connect */
94 static int bgp_md5_set_connect(int socket, union sockunion *su,
95 const char *password)
96 {
97 int ret = -1;
98
99 #if HAVE_DECL_TCP_MD5SIG
100 frr_elevate_privs(&bgpd_privs) {
101 ret = bgp_md5_set_socket(socket, su, password);
102 }
103 #endif /* HAVE_TCP_MD5SIG */
104
105 return ret;
106 }
107
108 static int bgp_md5_set_password(struct peer *peer, const char *password)
109 {
110 struct listnode *node;
111 int ret = 0;
112 struct bgp_listener *listener;
113
114 frr_elevate_privs(&bgpd_privs) {
115 /* Set or unset the password on the listen socket(s). Outbound
116 * connections are taken care of in bgp_connect() below.
117 */
118 for (ALL_LIST_ELEMENTS_RO(bm->listen_sockets, node, listener))
119 if (listener->su.sa.sa_family
120 == peer->su.sa.sa_family) {
121 ret = bgp_md5_set_socket(listener->fd,
122 &peer->su, password);
123 break;
124 }
125 }
126 return ret;
127 }
128
129 int bgp_md5_set(struct peer *peer)
130 {
131 /* Set the password from listen socket. */
132 return bgp_md5_set_password(peer, peer->password);
133 }
134
135 int bgp_md5_unset(struct peer *peer)
136 {
137 /* Unset the password from listen socket. */
138 return bgp_md5_set_password(peer, NULL);
139 }
140
141 int bgp_set_socket_ttl(struct peer *peer, int bgp_sock)
142 {
143 char buf[INET_ADDRSTRLEN];
144 int ret = 0;
145
146 /* In case of peer is EBGP, we should set TTL for this connection. */
147 if (!peer->gtsm_hops && (peer_sort(peer) == BGP_PEER_EBGP)) {
148 ret = sockopt_ttl(peer->su.sa.sa_family, bgp_sock, peer->ttl);
149 if (ret) {
150 flog_err(
151 LIB_ERR_SOCKET,
152 "%s: Can't set TxTTL on peer (rtrid %s) socket, err = %d",
153 __func__,
154 inet_ntop(AF_INET, &peer->remote_id, buf,
155 sizeof(buf)),
156 errno);
157 return ret;
158 }
159 } else if (peer->gtsm_hops) {
160 /* On Linux, setting minttl without setting ttl seems to mess
161 with the
162 outgoing ttl. Therefore setting both.
163 */
164 ret = sockopt_ttl(peer->su.sa.sa_family, bgp_sock, MAXTTL);
165 if (ret) {
166 flog_err(
167 LIB_ERR_SOCKET,
168 "%s: Can't set TxTTL on peer (rtrid %s) socket, err = %d",
169 __func__,
170 inet_ntop(AF_INET, &peer->remote_id, buf,
171 sizeof(buf)),
172 errno);
173 return ret;
174 }
175 ret = sockopt_minttl(peer->su.sa.sa_family, bgp_sock,
176 MAXTTL + 1 - peer->gtsm_hops);
177 if (ret) {
178 flog_err(
179 LIB_ERR_SOCKET,
180 "%s: Can't set MinTTL on peer (rtrid %s) socket, err = %d",
181 __func__,
182 inet_ntop(AF_INET, &peer->remote_id, buf,
183 sizeof(buf)),
184 errno);
185 return ret;
186 }
187 }
188
189 return ret;
190 }
191
192 /*
193 * Obtain the BGP instance that the incoming connection should be processed
194 * against. This is important because more than one VRF could be using the
195 * same IP address space. The instance is got by obtaining the device to
196 * which the incoming connection is bound to. This could either be a VRF
197 * or it could be an interface, which in turn determines the VRF.
198 */
199 static int bgp_get_instance_for_inc_conn(int sock, struct bgp **bgp_inst)
200 {
201 #ifndef SO_BINDTODEVICE
202 /* only Linux has SO_BINDTODEVICE, but we're in Linux-specific code here
203 * anyway since the assumption is that the interface name returned by
204 * getsockopt() is useful in identifying the VRF, particularly with
205 * Linux's
206 * VRF l3master device. The whole mechanism is specific to Linux, so...
207 * when other platforms add VRF support, this will need handling here as
208 * well. (or, some restructuring) */
209 *bgp_inst = bgp_get_default();
210 return !*bgp_inst;
211
212 #else
213 char name[VRF_NAMSIZ + 1];
214 socklen_t name_len = VRF_NAMSIZ;
215 struct bgp *bgp;
216 int rc;
217 struct listnode *node, *nnode;
218
219 *bgp_inst = NULL;
220 name[0] = '\0';
221 rc = getsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, name, &name_len);
222 if (rc != 0) {
223 #if defined(HAVE_CUMULUS)
224 flog_err(
225 LIB_ERR_SOCKET,
226 "[Error] BGP SO_BINDTODEVICE get failed (%s), sock %d",
227 safe_strerror(errno), sock);
228 return -1;
229 #endif
230 }
231
232 if (!strlen(name)) {
233 *bgp_inst = bgp_get_default();
234 return 0; /* default instance. */
235 }
236
237 /* First try match to instance; if that fails, check for interfaces. */
238 bgp = bgp_lookup_by_name(name);
239 if (bgp) {
240 if (!bgp->vrf_id) // unexpected
241 return -1;
242 *bgp_inst = bgp;
243 return 0;
244 }
245
246 /* TODO - This will be optimized once interfaces move into the NS */
247 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
248 struct interface *ifp;
249
250 if (bgp->inst_type == BGP_INSTANCE_TYPE_VIEW)
251 continue;
252
253 ifp = if_lookup_by_name(name, bgp->vrf_id);
254 if (ifp) {
255 *bgp_inst = bgp;
256 return 0;
257 }
258 }
259
260 /* We didn't match to either an instance or an interface. */
261 return -1;
262 #endif
263 }
264
265 /* Accept bgp connection. */
266 static int bgp_accept(struct thread *thread)
267 {
268 int bgp_sock;
269 int accept_sock;
270 union sockunion su;
271 struct bgp_listener *listener = THREAD_ARG(thread);
272 struct peer *peer;
273 struct peer *peer1;
274 char buf[SU_ADDRSTRLEN];
275 struct bgp *bgp = NULL;
276
277 sockunion_init(&su);
278
279 /* Register accept thread. */
280 accept_sock = THREAD_FD(thread);
281 if (accept_sock < 0) {
282 flog_err_sys(LIB_ERR_SOCKET, "accept_sock is nevative value %d",
283 accept_sock);
284 return -1;
285 }
286 listener->thread = NULL;
287
288 thread_add_read(bm->master, bgp_accept, listener, accept_sock,
289 &listener->thread);
290
291 /* Accept client connection. */
292 bgp_sock = sockunion_accept(accept_sock, &su);
293 if (bgp_sock < 0) {
294 flog_err_sys(LIB_ERR_SOCKET,
295 "[Error] BGP socket accept failed (%s)",
296 safe_strerror(errno));
297 return -1;
298 }
299 set_nonblocking(bgp_sock);
300
301 /* Obtain BGP instance this connection is meant for.
302 * - if it is a VRF netns sock, then BGP is in listener structure
303 * - otherwise, the bgp instance need to be demultiplexed
304 */
305 if (listener->bgp)
306 bgp = listener->bgp;
307 else if (bgp_get_instance_for_inc_conn(bgp_sock, &bgp)) {
308 if (bgp_debug_neighbor_events(NULL))
309 zlog_debug(
310 "[Event] Could not get instance for incoming conn from %s",
311 inet_sutop(&su, buf));
312 close(bgp_sock);
313 return -1;
314 }
315
316 /* Set socket send buffer size */
317 setsockopt_so_sendbuf(bgp_sock, BGP_SOCKET_SNDBUF_SIZE);
318
319 /* Check remote IP address */
320 peer1 = peer_lookup(bgp, &su);
321
322 if (!peer1) {
323 peer1 = peer_lookup_dynamic_neighbor(bgp, &su);
324 if (peer1) {
325 /* Dynamic neighbor has been created, let it proceed */
326 peer1->fd = bgp_sock;
327 bgp_fsm_change_status(peer1, Active);
328 BGP_TIMER_OFF(
329 peer1->t_start); /* created in peer_create() */
330
331 if (peer_active(peer1))
332 BGP_EVENT_ADD(peer1, TCP_connection_open);
333
334 return 0;
335 }
336 }
337
338 if (!peer1) {
339 if (bgp_debug_neighbor_events(NULL)) {
340 zlog_debug(
341 "[Event] %s connection rejected - not configured"
342 " and not valid for dynamic",
343 inet_sutop(&su, buf));
344 }
345 close(bgp_sock);
346 return -1;
347 }
348
349 if (CHECK_FLAG(peer1->flags, PEER_FLAG_SHUTDOWN)) {
350 if (bgp_debug_neighbor_events(peer1))
351 zlog_debug(
352 "[Event] connection from %s rejected due to admin shutdown",
353 inet_sutop(&su, buf));
354 close(bgp_sock);
355 return -1;
356 }
357
358 /*
359 * Do not accept incoming connections in Clearing state. This can result
360 * in incorect state transitions - e.g., the connection goes back to
361 * Established and then the Clearing_Completed event is generated. Also,
362 * block incoming connection in Deleted state.
363 */
364 if (peer1->status == Clearing || peer1->status == Deleted) {
365 if (bgp_debug_neighbor_events(peer1))
366 zlog_debug(
367 "[Event] Closing incoming conn for %s (%p) state %d",
368 peer1->host, peer1, peer1->status);
369 close(bgp_sock);
370 return -1;
371 }
372
373 /* Check that at least one AF is activated for the peer. */
374 if (!peer_active(peer1)) {
375 if (bgp_debug_neighbor_events(peer1))
376 zlog_debug(
377 "%s - incoming conn rejected - no AF activated for peer",
378 peer1->host);
379 close(bgp_sock);
380 return -1;
381 }
382
383 if (bgp_debug_neighbor_events(peer1))
384 zlog_debug("[Event] BGP connection from host %s fd %d",
385 inet_sutop(&su, buf), bgp_sock);
386
387 if (peer1->doppelganger) {
388 /* We have an existing connection. Kill the existing one and run
389 with this one.
390 */
391 if (bgp_debug_neighbor_events(peer1))
392 zlog_debug(
393 "[Event] New active connection from peer %s, Killing"
394 " previous active connection",
395 peer1->host);
396 peer_delete(peer1->doppelganger);
397 }
398
399 if (bgp_set_socket_ttl(peer1, bgp_sock) < 0)
400 if (bgp_debug_neighbor_events(peer1))
401 zlog_debug(
402 "[Event] Unable to set min/max TTL on peer %s, Continuing",
403 peer1->host);
404
405 peer = peer_create(&su, peer1->conf_if, peer1->bgp, peer1->local_as,
406 peer1->as, peer1->as_type, 0, 0, NULL);
407 peer->su = su;
408 hash_release(peer->bgp->peerhash, peer);
409 hash_get(peer->bgp->peerhash, peer, hash_alloc_intern);
410
411 peer_xfer_config(peer, peer1);
412 UNSET_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE);
413
414 peer->doppelganger = peer1;
415 peer1->doppelganger = peer;
416 peer->fd = bgp_sock;
417 vrf_bind(peer->bgp->vrf_id, bgp_sock, bgp_get_bound_name(peer));
418 bgp_fsm_change_status(peer, Active);
419 BGP_TIMER_OFF(peer->t_start); /* created in peer_create() */
420
421 SET_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER);
422
423 /* Make dummy peer until read Open packet. */
424 if (peer1->status == Established
425 && CHECK_FLAG(peer1->sflags, PEER_STATUS_NSF_MODE)) {
426 /* If we have an existing established connection with graceful
427 * restart
428 * capability announced with one or more address families, then
429 * drop
430 * existing established connection and move state to connect.
431 */
432 peer1->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
433 SET_FLAG(peer1->sflags, PEER_STATUS_NSF_WAIT);
434 bgp_event_update(peer1, TCP_connection_closed);
435 }
436
437 if (peer_active(peer)) {
438 BGP_EVENT_ADD(peer, TCP_connection_open);
439 }
440
441 return 0;
442 }
443
444 /* BGP socket bind. */
445 static char *bgp_get_bound_name(struct peer *peer)
446 {
447 char *name = NULL;
448
449 if (!peer)
450 return NULL;
451
452 if ((peer->bgp->vrf_id == VRF_DEFAULT) && !peer->ifname
453 && !peer->conf_if)
454 return NULL;
455
456 if (peer->su.sa.sa_family != AF_INET
457 && peer->su.sa.sa_family != AF_INET6)
458 return NULL; // unexpected
459
460 /* For IPv6 peering, interface (unnumbered or link-local with interface)
461 * takes precedence over VRF. For IPv4 peering, explicit interface or
462 * VRF are the situations to bind.
463 */
464 if (peer->su.sa.sa_family == AF_INET6)
465 name = (peer->conf_if ? peer->conf_if
466 : (peer->ifname ? peer->ifname
467 : peer->bgp->name));
468 else
469 name = peer->ifname ? peer->ifname : peer->bgp->name;
470
471 return name;
472 }
473
474 static int bgp_update_address(struct interface *ifp, const union sockunion *dst,
475 union sockunion *addr)
476 {
477 struct prefix *p, *sel, d;
478 struct connected *connected;
479 struct listnode *node;
480 int common;
481
482 sockunion2hostprefix(dst, &d);
483 sel = NULL;
484 common = -1;
485
486 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected)) {
487 p = connected->address;
488 if (p->family != d.family)
489 continue;
490 if (prefix_common_bits(p, &d) > common) {
491 sel = p;
492 common = prefix_common_bits(sel, &d);
493 }
494 }
495
496 if (!sel)
497 return 1;
498
499 prefix2sockunion(sel, addr);
500 return 0;
501 }
502
503 /* Update source selection. */
504 static int bgp_update_source(struct peer *peer)
505 {
506 struct interface *ifp;
507 union sockunion addr;
508 int ret = 0;
509
510 sockunion_init(&addr);
511
512 /* Source is specified with interface name. */
513 if (peer->update_if) {
514 ifp = if_lookup_by_name(peer->update_if, peer->bgp->vrf_id);
515 if (!ifp)
516 return -1;
517
518 if (bgp_update_address(ifp, &peer->su, &addr))
519 return -1;
520
521 ret = sockunion_bind(peer->fd, &addr, 0, &addr);
522 }
523
524 /* Source is specified with IP address. */
525 if (peer->update_source)
526 ret = sockunion_bind(peer->fd, peer->update_source, 0,
527 peer->update_source);
528
529 return ret;
530 }
531
532 #define DATAPLANE_MARK 254 /* main table ID */
533
534 /* BGP try to connect to the peer. */
535 int bgp_connect(struct peer *peer)
536 {
537 assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_WRITES_ON));
538 assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_READS_ON));
539 ifindex_t ifindex = 0;
540
541 if (peer->conf_if && BGP_PEER_SU_UNSPEC(peer)) {
542 zlog_debug("Peer address not learnt: Returning from connect");
543 return 0;
544 }
545 frr_elevate_privs(&bgpd_privs) {
546 /* Make socket for the peer. */
547 peer->fd = vrf_sockunion_socket(&peer->su, peer->bgp->vrf_id,
548 bgp_get_bound_name(peer));
549 }
550 if (peer->fd < 0)
551 return -1;
552
553 set_nonblocking(peer->fd);
554
555 /* Set socket send buffer size */
556 setsockopt_so_sendbuf(peer->fd, BGP_SOCKET_SNDBUF_SIZE);
557
558 if (bgp_set_socket_ttl(peer, peer->fd) < 0)
559 return -1;
560
561 sockopt_reuseaddr(peer->fd);
562 sockopt_reuseport(peer->fd);
563 if (sockopt_mark_default(peer->fd, DATAPLANE_MARK, &bgpd_privs) < 0)
564 zlog_warn("Unable to set mark on FD for peer %s, err=%s",
565 peer->host, safe_strerror(errno));
566
567 #ifdef IPTOS_PREC_INTERNETCONTROL
568 frr_elevate_privs(&bgpd_privs) {
569 if (sockunion_family(&peer->su) == AF_INET)
570 setsockopt_ipv4_tos(peer->fd,
571 IPTOS_PREC_INTERNETCONTROL);
572 else if (sockunion_family(&peer->su) == AF_INET6)
573 setsockopt_ipv6_tclass(peer->fd,
574 IPTOS_PREC_INTERNETCONTROL);
575 }
576 #endif
577
578 if (peer->password)
579 bgp_md5_set_connect(peer->fd, &peer->su, peer->password);
580
581 /* Update source bind. */
582 if (bgp_update_source(peer) < 0) {
583 return connect_error;
584 }
585
586 if (peer->conf_if || peer->ifname)
587 ifindex = ifname2ifindex(peer->conf_if ? peer->conf_if
588 : peer->ifname,
589 peer->bgp->vrf_id);
590
591 if (bgp_debug_neighbor_events(peer))
592 zlog_debug("%s [Event] Connect start to %s fd %d", peer->host,
593 peer->host, peer->fd);
594
595 /* Connect to the remote peer. */
596 return sockunion_connect(peer->fd, &peer->su, htons(peer->port),
597 ifindex);
598 }
599
600 /* After TCP connection is established. Get local address and port. */
601 int bgp_getsockname(struct peer *peer)
602 {
603 if (peer->su_local) {
604 sockunion_free(peer->su_local);
605 peer->su_local = NULL;
606 }
607
608 if (peer->su_remote) {
609 sockunion_free(peer->su_remote);
610 peer->su_remote = NULL;
611 }
612
613 peer->su_local = sockunion_getsockname(peer->fd);
614 if (!peer->su_local)
615 return -1;
616 peer->su_remote = sockunion_getpeername(peer->fd);
617 if (!peer->su_remote)
618 return -1;
619
620 if (bgp_nexthop_set(peer->su_local, peer->su_remote, &peer->nexthop,
621 peer)) {
622 #if defined(HAVE_CUMULUS)
623 flog_err(
624 BGP_ERR_NH_UPD,
625 "%s: nexthop_set failed, resetting connection - intf %p",
626 peer->host, peer->nexthop.ifp);
627 return -1;
628 #endif
629 }
630 return 0;
631 }
632
633
634 static int bgp_listener(int sock, struct sockaddr *sa, socklen_t salen,
635 struct bgp *bgp)
636 {
637 struct bgp_listener *listener;
638 int ret, en;
639
640 sockopt_reuseaddr(sock);
641 sockopt_reuseport(sock);
642
643 frr_elevate_privs(&bgpd_privs) {
644
645 #ifdef IPTOS_PREC_INTERNETCONTROL
646 if (sa->sa_family == AF_INET)
647 setsockopt_ipv4_tos(sock, IPTOS_PREC_INTERNETCONTROL);
648 else if (sa->sa_family == AF_INET6)
649 setsockopt_ipv6_tclass(sock,
650 IPTOS_PREC_INTERNETCONTROL);
651 #endif
652
653 sockopt_v6only(sa->sa_family, sock);
654
655 ret = bind(sock, sa, salen);
656 en = errno;
657 }
658
659 if (ret < 0) {
660 flog_err_sys(LIB_ERR_SOCKET, "bind: %s", safe_strerror(en));
661 return ret;
662 }
663
664 ret = listen(sock, SOMAXCONN);
665 if (ret < 0) {
666 flog_err_sys(LIB_ERR_SOCKET, "listen: %s",
667 safe_strerror(errno));
668 return ret;
669 }
670
671 listener = XCALLOC(MTYPE_BGP_LISTENER, sizeof(*listener));
672 listener->fd = sock;
673
674 /* this socket needs a change of ns. record bgp back pointer */
675 if (bgp->vrf_id != VRF_DEFAULT && vrf_is_mapped_on_netns(bgp->vrf_id))
676 listener->bgp = bgp;
677
678 memcpy(&listener->su, sa, salen);
679 listener->thread = NULL;
680 thread_add_read(bm->master, bgp_accept, listener, sock,
681 &listener->thread);
682 listnode_add(bm->listen_sockets, listener);
683
684 return 0;
685 }
686
687 /* IPv6 supported version of BGP server socket setup. */
688 int bgp_socket(struct bgp *bgp, unsigned short port, const char *address)
689 {
690 struct addrinfo *ainfo;
691 struct addrinfo *ainfo_save;
692 static const struct addrinfo req = {
693 .ai_family = AF_UNSPEC,
694 .ai_flags = AI_PASSIVE,
695 .ai_socktype = SOCK_STREAM,
696 };
697 int ret, count;
698 char port_str[BUFSIZ];
699
700 snprintf(port_str, sizeof(port_str), "%d", port);
701 port_str[sizeof(port_str) - 1] = '\0';
702
703 frr_elevate_privs(&bgpd_privs) {
704 ret = vrf_getaddrinfo(address, port_str, &req, &ainfo_save,
705 bgp->vrf_id);
706 }
707 if (ret != 0) {
708 flog_err_sys(LIB_ERR_SOCKET, "getaddrinfo: %s",
709 gai_strerror(ret));
710 return -1;
711 }
712
713 count = 0;
714 for (ainfo = ainfo_save; ainfo; ainfo = ainfo->ai_next) {
715 int sock;
716
717 if (ainfo->ai_family != AF_INET && ainfo->ai_family != AF_INET6)
718 continue;
719
720 frr_elevate_privs(&bgpd_privs) {
721 sock = vrf_socket(ainfo->ai_family,
722 ainfo->ai_socktype,
723 ainfo->ai_protocol, bgp->vrf_id,
724 (bgp->inst_type
725 == BGP_INSTANCE_TYPE_VRF
726 ? bgp->name : NULL));
727 }
728 if (sock < 0) {
729 flog_err_sys(LIB_ERR_SOCKET, "socket: %s",
730 safe_strerror(errno));
731 continue;
732 }
733
734 /* if we intend to implement ttl-security, this socket needs
735 * ttl=255 */
736 sockopt_ttl(ainfo->ai_family, sock, MAXTTL);
737
738 ret = bgp_listener(sock, ainfo->ai_addr, ainfo->ai_addrlen,
739 bgp);
740 if (ret == 0)
741 ++count;
742 else
743 close(sock);
744 }
745 freeaddrinfo(ainfo_save);
746 if (count == 0 && bgp->inst_type != BGP_INSTANCE_TYPE_VRF) {
747 flog_err(
748 LIB_ERR_SOCKET,
749 "%s: no usable addresses please check other programs usage of specified port %d",
750 __func__, port);
751 flog_err_sys(LIB_ERR_SOCKET, "%s: Program cannot continue",
752 __func__);
753 exit(-1);
754 }
755
756 return 0;
757 }
758
759 /* this function closes vrf socket
760 * this should be called only for vrf socket with netns backend
761 */
762 void bgp_close_vrf_socket(struct bgp *bgp)
763 {
764 struct listnode *node, *next;
765 struct bgp_listener *listener;
766
767 if (!bgp)
768 return;
769
770 if (bm->listen_sockets == NULL)
771 return;
772
773 for (ALL_LIST_ELEMENTS(bm->listen_sockets, node, next, listener)) {
774 if (listener->bgp == bgp) {
775 thread_cancel(listener->thread);
776 close(listener->fd);
777 listnode_delete(bm->listen_sockets, listener);
778 XFREE(MTYPE_BGP_LISTENER, listener);
779 }
780 }
781 }
782
783 /* this function closes main socket
784 */
785 void bgp_close(void)
786 {
787 struct listnode *node, *next;
788 struct bgp_listener *listener;
789
790 if (bm->listen_sockets == NULL)
791 return;
792
793 for (ALL_LIST_ELEMENTS(bm->listen_sockets, node, next, listener)) {
794 if (listener->bgp)
795 continue;
796 thread_cancel(listener->thread);
797 close(listener->fd);
798 listnode_delete(bm->listen_sockets, listener);
799 XFREE(MTYPE_BGP_LISTENER, listener);
800 }
801 }