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