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