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