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